Branch data Line data Source code
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 : :
15 : : #include "character_string.h"
16 : : #include "rdata.h"
17 : :
18 : : using namespace std;
19 : : using namespace isc::dns::rdata;
20 : :
21 : : namespace isc {
22 : : namespace dns {
23 : :
24 : : namespace {
25 : : bool isDigit(char c) {
26 : 19 : return (('0' <= c) && (c <= '9'));
27 : : }
28 : : }
29 : :
30 : : std::string
31 : 190 : characterstr::getNextCharacterString(const std::string& input_str,
32 : : std::string::const_iterator& input_iterator)
33 : : {
34 : 7 : string result;
35 : :
36 : : // If the input string only contains white-spaces, it is an invalid
37 : : // <character-string>
38 [ - + ]: 190 : if (input_iterator >= input_str.end()) {
39 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Invalid text format, \
40 : : <character-string> field is missing.");
41 : : }
42 : :
43 : : // Whether the <character-string> is separated with double quotes (")
44 : 190 : bool quotes_separated = (*input_iterator == '"');
45 : : // Whether the quotes are pared if the string is quotes separated
46 : 190 : bool quotes_paired = false;
47 : :
48 [ + + ]: 190 : if (quotes_separated) {
49 : : ++input_iterator;
50 : : }
51 : :
52 [ + + ]: 1767 : while(input_iterator < input_str.end()){
53 : : // Escaped characters processing
54 [ + + ]: 1757 : if (*input_iterator == '\\') {
55 [ - + ]: 8 : if (input_iterator + 1 == input_str.end()) {
56 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "<character-string> ended \
57 : : prematurely.");
58 : : } else {
59 [ + + ]: 8 : if (isDigit(*(input_iterator + 1))) {
60 : : // \DDD where each D is a digit. It its the octet
61 : : // corresponding to the decimal number described by DDD
62 [ + + ]: 5 : if (input_iterator + 3 >= input_str.end()) {
63 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "<character-string> ended \
64 : : prematurely.");
65 : : } else {
66 : 4 : int n = 0;
67 : : ++input_iterator;
68 [ + + ]: 13 : for (int i = 0; i < 3; ++i) {
69 [ + + ]: 11 : if (isDigit(*input_iterator)) {
70 : 18 : n = n*10 + (*input_iterator - '0');
71 : : ++input_iterator;
72 : : } else {
73 [ + - ][ + - ]: 4 : isc_throw(InvalidRdataText, "Illegal decimal \
74 : : escaping series");
75 : : }
76 : : }
77 [ - + ]: 2 : if (n > 255) {
78 [ # # ][ # # ]: 0 : isc_throw(InvalidRdataText, "Illegal octet \
79 : : number");
80 : : }
81 [ + - ]: 2 : result.push_back(n);
82 : 2 : continue;
83 : : }
84 : : } else {
85 : : ++input_iterator;
86 [ + - ]: 3 : result.push_back(*input_iterator);
87 : : ++input_iterator;
88 : 3 : continue;
89 : : }
90 : : }
91 : : }
92 : :
93 [ + + ]: 1749 : if (quotes_separated) {
94 : : // If the <character-string> is seperated with quotes symbol and
95 : : // another quotes symbol is encountered, it is the end of the
96 : : // <character-string>
97 [ + + ]: 889 : if (*input_iterator == '"') {
98 : 170 : quotes_paired = true;
99 : : ++input_iterator;
100 : : // Reach the end of character string
101 : : break;
102 : : }
103 [ + + ]: 860 : } else if (*input_iterator == ' ') {
104 : : // If the <character-string> is not seperated with quotes symbol,
105 : : // it is seperated with <space> char
106 : : break;
107 : : }
108 : :
109 [ + - ]: 1572 : result.push_back(*input_iterator);
110 : :
111 : : ++input_iterator;
112 : : }
113 : :
114 [ + + ]: 187 : if (result.size() > MAX_CHARSTRING_LEN) {
115 [ + - ][ + - ]: 6 : isc_throw(CharStringTooLong, "<character-string> is too long");
116 : : }
117 : :
118 [ + + ][ + + ]: 184 : if (quotes_separated && !quotes_paired) {
119 [ + - ][ + - ]: 2 : isc_throw(InvalidRdataText, "The quotes are not paired");
120 : : }
121 : :
122 : 183 : return (result);
123 : : }
124 : :
125 : : std::string
126 : 5 : characterstr::getNextCharacterString(util::InputBuffer& buffer, size_t len) {
127 : 5 : uint8_t str_len = buffer.readUint8();
128 : :
129 : 5 : size_t pos = buffer.getPosition();
130 [ - + ]: 5 : if (len - pos < str_len) {
131 [ # # ]: 0 : isc_throw(InvalidRdataLength, "Invalid string length");
132 : : }
133 : :
134 : : uint8_t buf[MAX_CHARSTRING_LEN];
135 : 5 : buffer.readData(buf, str_len);
136 : 5 : return (string(buf, buf + str_len));
137 : : }
138 : :
139 : : } // end of namespace dns
140 : 6210 : } // end of namespace isc
|