… | |
… | |
192 | ///////////////////////////////////////////////////////////////////////////// |
192 | ///////////////////////////////////////////////////////////////////////////// |
193 | // fp hell |
193 | // fp hell |
194 | |
194 | |
195 | // scan a group of digits, and a trailing exponent |
195 | // scan a group of digits, and a trailing exponent |
196 | static void |
196 | static void |
197 | json_atof_scan1 (const char *s, NV *accum, int *expo, int postdp) |
197 | json_atof_scan1 (const char *s, NV *accum, int *expo, int postdp, int maxdepth) |
198 | { |
198 | { |
199 | UV uaccum = 0; |
199 | UV uaccum = 0; |
200 | int eaccum = 0; |
200 | int eaccum = 0; |
|
|
201 | |
|
|
202 | // if we recurse too deep, skip all remaining digits |
|
|
203 | // to avoid a stack overflow attack |
|
|
204 | if (expect_false (--maxdepth <= 0)) |
|
|
205 | while (((U8)*s - '0') < 10) |
|
|
206 | ++s; |
201 | |
207 | |
202 | for (;;) |
208 | for (;;) |
203 | { |
209 | { |
204 | U8 dig = (U8)*s - '0'; |
210 | U8 dig = (U8)*s - '0'; |
205 | |
211 | |
206 | if (expect_false (dig >= 10)) |
212 | if (expect_false (dig >= 10)) |
207 | { |
213 | { |
208 | if (dig == (U8)((U8)'.' - (U8)'0')) |
214 | if (dig == (U8)((U8)'.' - (U8)'0')) |
209 | { |
215 | { |
210 | ++s; |
216 | ++s; |
211 | json_atof_scan1 (s, accum, expo, 1); |
217 | json_atof_scan1 (s, accum, expo, 1, maxdepth); |
212 | } |
218 | } |
213 | else if ((dig | ' ') == 'e' - '0') |
219 | else if ((dig | ' ') == 'e' - '0') |
214 | { |
220 | { |
215 | int exp2 = 0; |
221 | int exp2 = 0; |
216 | int neg = 0; |
222 | int neg = 0; |
… | |
… | |
242 | // if we have too many digits, then recurse for more |
248 | // if we have too many digits, then recurse for more |
243 | // we actually do this for rather few digits |
249 | // we actually do this for rather few digits |
244 | if (uaccum >= (UV_MAX - 9) / 10) |
250 | if (uaccum >= (UV_MAX - 9) / 10) |
245 | { |
251 | { |
246 | if (postdp) *expo -= eaccum; |
252 | if (postdp) *expo -= eaccum; |
247 | json_atof_scan1 (s, accum, expo, postdp); |
253 | json_atof_scan1 (s, accum, expo, postdp, maxdepth); |
248 | if (postdp) *expo += eaccum; |
254 | if (postdp) *expo += eaccum; |
249 | |
255 | |
250 | break; |
256 | break; |
251 | } |
257 | } |
252 | } |
258 | } |
… | |
… | |
270 | { |
276 | { |
271 | ++s; |
277 | ++s; |
272 | neg = 1; |
278 | neg = 1; |
273 | } |
279 | } |
274 | |
280 | |
|
|
281 | // a recursion depth of ten gives us >>500 bits |
275 | json_atof_scan1 (s, &accum, &expo, 0); |
282 | json_atof_scan1 (s, &accum, &expo, 0, 10); |
276 | |
283 | |
277 | return neg ? -accum : accum; |
284 | return neg ? -accum : accum; |
278 | } |
285 | } |
279 | ///////////////////////////////////////////////////////////////////////////// |
286 | ///////////////////////////////////////////////////////////////////////////// |
280 | // encoder |
287 | // encoder |