ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/JSON-XS/XS.xs
(Generate patch)

Comparing JSON-XS/XS.xs (file contents):
Revision 1.104 by root, Tue Jan 19 00:31:13 2010 UTC vs.
Revision 1.106 by root, Tue Jan 19 01:36:34 2010 UTC

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
196static void 196static void
197json_atof_scan1 (const char *s, NV *accum, int *expo, int postdp) 197json_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 }
253 259
260 // this relies greatly on the quality of the pow ()
261 // implementation of the platform, but a good
262 // implementation is hard to beat.
254 if (postdp) *expo -= eaccum; 263 if (postdp) *expo -= eaccum;
255 *accum += uaccum * pow (10., *expo); 264 *accum += uaccum * Perl_pow (10., *expo);
256 *expo += eaccum; 265 *expo += eaccum;
257} 266}
258 267
259static NV 268static NV
260json_atof (const char *s) 269json_atof (const char *s)
267 { 276 {
268 ++s; 277 ++s;
269 neg = 1; 278 neg = 1;
270 } 279 }
271 280
281 // a recursion depth of ten gives us >>500 bits
272 json_atof_scan1 (s, &accum, &expo, 0); 282 json_atof_scan1 (s, &accum, &expo, 0, 10);
273 283
274 return neg ? -accum : accum; 284 return neg ? -accum : accum;
275} 285}
276///////////////////////////////////////////////////////////////////////////// 286/////////////////////////////////////////////////////////////////////////////
277// encoder 287// encoder

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines