@@ -43,21 +43,21 @@ static const char *hatoui(const char *first, const char *last,
4343}
4444
4545enum jtokentype getJsonToken (string& tokenVal, unsigned int & consumed,
46- const char *raw)
46+ const char *raw, const char *end )
4747{
4848 tokenVal.clear ();
4949 consumed = 0 ;
5050
5151 const char *rawStart = raw;
5252
53- while ((* raw) && (json_isspace (*raw))) // skip whitespace
53+ while (raw < end && (json_isspace (*raw))) // skip whitespace
5454 raw++;
5555
56- switch (*raw) {
57-
58- case 0 :
56+ if (raw >= end)
5957 return JTOK_NONE;
6058
59+ switch (*raw) {
60+
6161 case ' {' :
6262 raw++;
6363 consumed = (raw - rawStart);
@@ -127,40 +127,40 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
127127 numStr += *raw; // copy first char
128128 raw++;
129129
130- if ((*first == ' -' ) && (!json_isdigit (*raw)))
130+ if ((*first == ' -' ) && (raw < end) && ( !json_isdigit (*raw)))
131131 return JTOK_ERR;
132132
133- while ((* raw) && json_isdigit (*raw)) { // copy digits
133+ while (raw < end && json_isdigit (*raw)) { // copy digits
134134 numStr += *raw;
135135 raw++;
136136 }
137137
138138 // part 2: frac
139- if (*raw == ' .' ) {
139+ if (raw < end && *raw == ' .' ) {
140140 numStr += *raw; // copy .
141141 raw++;
142142
143- if (!json_isdigit (*raw))
143+ if (raw >= end || !json_isdigit (*raw))
144144 return JTOK_ERR;
145- while ((* raw) && json_isdigit (*raw)) { // copy digits
145+ while (raw < end && json_isdigit (*raw)) { // copy digits
146146 numStr += *raw;
147147 raw++;
148148 }
149149 }
150150
151151 // part 3: exp
152- if (*raw == ' e' || *raw == ' E' ) {
152+ if (raw < end && ( *raw == ' e' || *raw == ' E' ) ) {
153153 numStr += *raw; // copy E
154154 raw++;
155155
156- if (*raw == ' -' || *raw == ' +' ) { // copy +/-
156+ if (raw < end && ( *raw == ' -' || *raw == ' +' ) ) { // copy +/-
157157 numStr += *raw;
158158 raw++;
159159 }
160160
161- if (!json_isdigit (*raw))
161+ if (raw >= end || !json_isdigit (*raw))
162162 return JTOK_ERR;
163- while ((* raw) && json_isdigit (*raw)) { // copy digits
163+ while (raw < end && json_isdigit (*raw)) { // copy digits
164164 numStr += *raw;
165165 raw++;
166166 }
@@ -177,13 +177,16 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
177177 string valStr;
178178 JSONUTF8StringFilter writer (valStr);
179179
180- while (* raw) {
180+ while (raw < end ) {
181181 if ((unsigned char )*raw < 0x20 )
182182 return JTOK_ERR;
183183
184184 else if (*raw == ' \\ ' ) {
185185 raw++; // skip backslash
186186
187+ if (raw >= end)
188+ return JTOK_ERR;
189+
187190 switch (*raw) {
188191 case ' "' : writer.push_back (' \" ' ); break ;
189192 case ' \\ ' : writer.push_back (' \\ ' ); break ;
@@ -196,7 +199,8 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
196199
197200 case ' u' : {
198201 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) !=
200204 raw + 1 + 4 )
201205 return JTOK_ERR;
202206 writer.push_back_u (codepoint);
@@ -246,7 +250,7 @@ enum expect_bits {
246250#define setExpect (bit ) (expectMask |= EXP_##bit)
247251#define clearExpect (bit ) (expectMask &= ~EXP_##bit)
248252
249- bool UniValue::read (const char *raw)
253+ bool UniValue::read (const char *raw, size_t size )
250254{
251255 clear ();
252256
@@ -257,10 +261,11 @@ bool UniValue::read(const char *raw)
257261 unsigned int consumed;
258262 enum jtokentype tok = JTOK_NONE;
259263 enum jtokentype last_tok = JTOK_NONE;
264+ const char * end = raw + size;
260265 do {
261266 last_tok = tok;
262267
263- tok = getJsonToken (tokenVal, consumed, raw);
268+ tok = getJsonToken (tokenVal, consumed, raw, end );
264269 if (tok == JTOK_NONE || tok == JTOK_ERR)
265270 return false ;
266271 raw += consumed;
@@ -432,10 +437,13 @@ bool UniValue::read(const char *raw)
432437 } while (!stack.empty ());
433438
434439 /* Check that nothing follows the initial construct (parsed above). */
435- tok = getJsonToken (tokenVal, consumed, raw);
440+ tok = getJsonToken (tokenVal, consumed, raw, end );
436441 if (tok != JTOK_NONE)
437442 return false ;
438443
439444 return true ;
440445}
441446
447+ bool UniValue::read (const char *raw) {
448+ return read (raw, strlen (raw));
449+ }
0 commit comments