character_string.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include "character_string.h"
  15. #include "rdata.h"
  16. using namespace std;
  17. using namespace isc::dns::rdata;
  18. namespace isc {
  19. namespace dns {
  20. namespace {
  21. bool isDigit(char c) {
  22. return (('0' <= c) && (c <= '9'));
  23. }
  24. }
  25. std::string
  26. characterstr::getNextCharacterString(const std::string& input_str,
  27. std::string::const_iterator& input_iterator)
  28. {
  29. string result;
  30. // If the input string only contains white-spaces, it is an invalid
  31. // <character-string>
  32. if (input_iterator >= input_str.end()) {
  33. isc_throw(InvalidRdataText, "Invalid text format, \
  34. <character-string> field is missing.");
  35. }
  36. // Whether the <character-string> is separated with double quotes (")
  37. bool quotes_separated = (*input_iterator == '"');
  38. // Whether the quotes are pared if the string is quotes separated
  39. bool quotes_paired = false;
  40. if (quotes_separated) {
  41. ++input_iterator;
  42. }
  43. while(input_iterator < input_str.end()){
  44. // Escaped characters processing
  45. if (*input_iterator == '\\') {
  46. if (input_iterator + 1 == input_str.end()) {
  47. isc_throw(InvalidRdataText, "<character-string> ended \
  48. prematurely.");
  49. } else {
  50. if (isDigit(*(input_iterator + 1))) {
  51. // \DDD where each D is a digit. It its the octet
  52. // corresponding to the decimal number described by DDD
  53. if (input_iterator + 3 >= input_str.end()) {
  54. isc_throw(InvalidRdataText, "<character-string> ended \
  55. prematurely.");
  56. } else {
  57. int n = 0;
  58. ++input_iterator;
  59. for (int i = 0; i < 3; ++i) {
  60. if (isDigit(*input_iterator)) {
  61. n = n*10 + (*input_iterator - '0');
  62. ++input_iterator;
  63. } else {
  64. isc_throw(InvalidRdataText, "Illegal decimal \
  65. escaping series");
  66. }
  67. }
  68. if (n > 255) {
  69. isc_throw(InvalidRdataText, "Illegal octet \
  70. number");
  71. }
  72. result.push_back(n);
  73. continue;
  74. }
  75. } else {
  76. ++input_iterator;
  77. result.push_back(*input_iterator);
  78. ++input_iterator;
  79. continue;
  80. }
  81. }
  82. }
  83. if (quotes_separated) {
  84. // If the <character-string> is seperated with quotes symbol and
  85. // another quotes symbol is encountered, it is the end of the
  86. // <character-string>
  87. if (*input_iterator == '"') {
  88. quotes_paired = true;
  89. ++input_iterator;
  90. // Reach the end of character string
  91. break;
  92. }
  93. } else if (*input_iterator == ' ') {
  94. // If the <character-string> is not seperated with quotes symbol,
  95. // it is seperated with <space> char
  96. break;
  97. }
  98. result.push_back(*input_iterator);
  99. ++input_iterator;
  100. }
  101. if (result.size() > MAX_CHARSTRING_LEN) {
  102. isc_throw(CharStringTooLong, "<character-string> is too long");
  103. }
  104. if (quotes_separated && !quotes_paired) {
  105. isc_throw(InvalidRdataText, "The quotes are not paired");
  106. }
  107. return (result);
  108. }
  109. std::string
  110. characterstr::getNextCharacterString(util::InputBuffer& buffer, size_t len) {
  111. uint8_t str_len = buffer.readUint8();
  112. size_t pos = buffer.getPosition();
  113. if (len - pos < str_len) {
  114. isc_throw(InvalidRdataLength, "Invalid string length");
  115. }
  116. uint8_t buf[MAX_CHARSTRING_LEN];
  117. buffer.readData(buf, str_len);
  118. return (string(buf, buf + str_len));
  119. }
  120. } // end of namespace dns
  121. } // end of namespace isc