@@ -43,21 +43,21 @@ static const char *hatoui(const char *first, const char *last,
43
43
}
44
44
45
45
enum jtokentype getJsonToken (string& tokenVal, unsigned int & consumed,
46
- const char *raw)
46
+ const char *raw, const char *end )
47
47
{
48
48
tokenVal.clear ();
49
49
consumed = 0 ;
50
50
51
51
const char *rawStart = raw;
52
52
53
- while ((* raw) && (json_isspace (*raw))) // skip whitespace
53
+ while (raw < end && (json_isspace (*raw))) // skip whitespace
54
54
raw++;
55
55
56
- switch (*raw) {
57
-
58
- case 0 :
56
+ if (raw >= end)
59
57
return JTOK_NONE;
60
58
59
+ switch (*raw) {
60
+
61
61
case ' {' :
62
62
raw++;
63
63
consumed = (raw - rawStart);
@@ -127,40 +127,40 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
127
127
numStr += *raw; // copy first char
128
128
raw++;
129
129
130
- if ((*first == ' -' ) && (!json_isdigit (*raw)))
130
+ if ((*first == ' -' ) && (raw < end) && ( !json_isdigit (*raw)))
131
131
return JTOK_ERR;
132
132
133
- while ((* raw) && json_isdigit (*raw)) { // copy digits
133
+ while (raw < end && json_isdigit (*raw)) { // copy digits
134
134
numStr += *raw;
135
135
raw++;
136
136
}
137
137
138
138
// part 2: frac
139
- if (*raw == ' .' ) {
139
+ if (raw < end && *raw == ' .' ) {
140
140
numStr += *raw; // copy .
141
141
raw++;
142
142
143
- if (!json_isdigit (*raw))
143
+ if (raw >= end || !json_isdigit (*raw))
144
144
return JTOK_ERR;
145
- while ((* raw) && json_isdigit (*raw)) { // copy digits
145
+ while (raw < end && json_isdigit (*raw)) { // copy digits
146
146
numStr += *raw;
147
147
raw++;
148
148
}
149
149
}
150
150
151
151
// part 3: exp
152
- if (*raw == ' e' || *raw == ' E' ) {
152
+ if (raw < end && ( *raw == ' e' || *raw == ' E' ) ) {
153
153
numStr += *raw; // copy E
154
154
raw++;
155
155
156
- if (*raw == ' -' || *raw == ' +' ) { // copy +/-
156
+ if (raw < end && ( *raw == ' -' || *raw == ' +' ) ) { // copy +/-
157
157
numStr += *raw;
158
158
raw++;
159
159
}
160
160
161
- if (!json_isdigit (*raw))
161
+ if (raw >= end || !json_isdigit (*raw))
162
162
return JTOK_ERR;
163
- while ((* raw) && json_isdigit (*raw)) { // copy digits
163
+ while (raw < end && json_isdigit (*raw)) { // copy digits
164
164
numStr += *raw;
165
165
raw++;
166
166
}
@@ -177,13 +177,16 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
177
177
string valStr;
178
178
JSONUTF8StringFilter writer (valStr);
179
179
180
- while (true ) {
180
+ while (raw < end ) {
181
181
if ((unsigned char )*raw < 0x20 )
182
182
return JTOK_ERR;
183
183
184
184
else if (*raw == ' \\ ' ) {
185
185
raw++; // skip backslash
186
186
187
+ if (raw >= end)
188
+ return JTOK_ERR;
189
+
187
190
switch (*raw) {
188
191
case ' "' : writer.push_back (' \" ' ); break ;
189
192
case ' \\ ' : writer.push_back (' \\ ' ); break ;
@@ -196,7 +199,8 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
196
199
197
200
case ' u' : {
198
201
unsigned int codepoint;
199
- if (hatoui (raw + 1 , raw + 1 + 4 , codepoint) !=
202
+ if (raw + 1 + 4 >= end ||
203
+ hatoui (raw + 1 , raw + 1 + 4 , codepoint) !=
200
204
raw + 1 + 4 )
201
205
return JTOK_ERR;
202
206
writer.push_back_u (codepoint);
@@ -246,7 +250,7 @@ enum expect_bits {
246
250
#define setExpect (bit ) (expectMask |= EXP_##bit)
247
251
#define clearExpect (bit ) (expectMask &= ~EXP_##bit)
248
252
249
- bool UniValue::read (const char *raw)
253
+ bool UniValue::read (const char *raw, size_t size )
250
254
{
251
255
clear ();
252
256
@@ -257,10 +261,11 @@ bool UniValue::read(const char *raw)
257
261
unsigned int consumed;
258
262
enum jtokentype tok = JTOK_NONE;
259
263
enum jtokentype last_tok = JTOK_NONE;
264
+ const char * end = raw + size;
260
265
do {
261
266
last_tok = tok;
262
267
263
- tok = getJsonToken (tokenVal, consumed, raw);
268
+ tok = getJsonToken (tokenVal, consumed, raw, end );
264
269
if (tok == JTOK_NONE || tok == JTOK_ERR)
265
270
return false ;
266
271
raw += consumed;
@@ -437,10 +442,13 @@ bool UniValue::read(const char *raw)
437
442
} while (!stack.empty ());
438
443
439
444
/* Check that nothing follows the initial construct (parsed above). */
440
- tok = getJsonToken (tokenVal, consumed, raw);
445
+ tok = getJsonToken (tokenVal, consumed, raw, end );
441
446
if (tok != JTOK_NONE)
442
447
return false ;
443
448
444
449
return true ;
445
450
}
446
451
452
+ bool UniValue::read (const char *raw) {
453
+ return read (raw, strlen (raw));
454
+ }
0 commit comments