… | |
… | |
79 | INCR_M_STR, // inside string |
79 | INCR_M_STR, // inside string |
80 | INCR_M_BS, // inside backslash |
80 | INCR_M_BS, // inside backslash |
81 | INCR_M_JSON // outside anything, count nesting |
81 | INCR_M_JSON // outside anything, count nesting |
82 | }; |
82 | }; |
83 | |
83 | |
84 | #define INCR_DONE(json) (!(json)->incr_nest && (json)->incr_mode == INCR_M_JSON) |
84 | #define INCR_DONE(json) ((json)->incr_nest <= 0 && (json)->incr_mode == INCR_M_JSON) |
85 | |
85 | |
86 | typedef struct { |
86 | typedef struct { |
87 | U32 flags; |
87 | U32 flags; |
88 | U32 max_depth; |
88 | U32 max_depth; |
89 | STRLEN max_size; |
89 | STRLEN max_size; |
… | |
… | |
92 | HV *cb_sk_object; |
92 | HV *cb_sk_object; |
93 | |
93 | |
94 | // for the incremental parser |
94 | // for the incremental parser |
95 | SV *incr_text; // the source text so far |
95 | SV *incr_text; // the source text so far |
96 | STRLEN incr_pos; // the current offset into the text |
96 | STRLEN incr_pos; // the current offset into the text |
97 | unsigned char incr_nest; // {[]}-nesting level |
97 | int incr_nest; // {[]}-nesting level |
98 | unsigned char incr_mode; |
98 | unsigned char incr_mode; |
99 | } JSON; |
99 | } JSON; |
100 | |
100 | |
101 | INLINE void |
101 | INLINE void |
102 | json_init (JSON *json) |
102 | json_init (JSON *json) |
… | |
… | |
194 | INLINE void |
194 | INLINE void |
195 | need (enc_t *enc, STRLEN len) |
195 | need (enc_t *enc, STRLEN len) |
196 | { |
196 | { |
197 | if (expect_false (enc->cur + len >= enc->end)) |
197 | if (expect_false (enc->cur + len >= enc->end)) |
198 | { |
198 | { |
199 | STRLEN cur = enc->cur - SvPVX (enc->sv); |
199 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
200 | SvGROW (enc->sv, cur + len + 1); |
200 | SvGROW (enc->sv, cur + len + 1); |
201 | enc->cur = SvPVX (enc->sv) + cur; |
201 | enc->cur = SvPVX (enc->sv) + cur; |
202 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
202 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
203 | } |
203 | } |
204 | } |
204 | } |
… | |
… | |
280 | (int)((uch - 0x10000) % 0x400 + 0xDC00)); |
280 | (int)((uch - 0x10000) % 0x400 + 0xDC00)); |
281 | enc->cur += 12; |
281 | enc->cur += 12; |
282 | } |
282 | } |
283 | else |
283 | else |
284 | { |
284 | { |
285 | static char hexdigit [16] = "0123456789abcdef"; |
|
|
286 | need (enc, len += 5); |
285 | need (enc, len += 5); |
287 | *enc->cur++ = '\\'; |
286 | *enc->cur++ = '\\'; |
288 | *enc->cur++ = 'u'; |
287 | *enc->cur++ = 'u'; |
289 | *enc->cur++ = hexdigit [ uch >> 12 ]; |
288 | *enc->cur++ = PL_hexdigit [ uch >> 12 ]; |
290 | *enc->cur++ = hexdigit [(uch >> 8) & 15]; |
289 | *enc->cur++ = PL_hexdigit [(uch >> 8) & 15]; |
291 | *enc->cur++ = hexdigit [(uch >> 4) & 15]; |
290 | *enc->cur++ = PL_hexdigit [(uch >> 4) & 15]; |
292 | *enc->cur++ = hexdigit [(uch >> 0) & 15]; |
291 | *enc->cur++ = PL_hexdigit [(uch >> 0) & 15]; |
293 | } |
292 | } |
294 | |
293 | |
295 | str += clen; |
294 | str += clen; |
296 | } |
295 | } |
297 | else if (enc->json.flags & F_LATIN1) |
296 | else if (enc->json.flags & F_LATIN1) |
… | |
… | |
461 | |
460 | |
462 | encode_ch (enc, '{'); |
461 | encode_ch (enc, '{'); |
463 | |
462 | |
464 | // for canonical output we have to sort by keys first |
463 | // for canonical output we have to sort by keys first |
465 | // actually, this is mostly due to the stupid so-called |
464 | // actually, this is mostly due to the stupid so-called |
466 | // security workaround added somewhere in 5.8.x. |
465 | // security workaround added somewhere in 5.8.x |
467 | // that randomises hash orderings |
466 | // that randomises hash orderings |
468 | if (enc->json.flags & F_CANONICAL) |
467 | if (enc->json.flags & F_CANONICAL) |
469 | { |
468 | { |
470 | int count = hv_iterinit (hv); |
469 | int count = hv_iterinit (hv); |
471 | |
470 | |
… | |
… | |
1411 | { |
1410 | { |
1412 | dec_t dec; |
1411 | dec_t dec; |
1413 | STRLEN offset; |
1412 | STRLEN offset; |
1414 | SV *sv; |
1413 | SV *sv; |
1415 | |
1414 | |
|
|
1415 | /* work around bugs in 5.10 where manipulating magic values |
|
|
1416 | * will perl ignore the magic in subsequent accesses |
|
|
1417 | */ |
1416 | SvGETMAGIC (string); |
1418 | /*SvGETMAGIC (string);*/ |
|
|
1419 | if (SvMAGICAL (string)) |
|
|
1420 | string = sv_2mortal (newSVsv (string)); |
|
|
1421 | |
1417 | SvUPGRADE (string, SVt_PV); |
1422 | SvUPGRADE (string, SVt_PV); |
1418 | |
1423 | |
1419 | /* work around a bug in perl 5.10, which causes SvCUR to fail an |
1424 | /* work around a bug in perl 5.10, which causes SvCUR to fail an |
1420 | * assertion with -DDEBUGGING, although SvCUR is documented to |
1425 | * assertion with -DDEBUGGING, although SvCUR is documented to |
1421 | * return the xpv_cur field which certainly exists after upgrading. |
1426 | * return the xpv_cur field which certainly exists after upgrading. |
1422 | * according to nicholas clark, calling SvPOK fixes this. |
1427 | * according to nicholas clark, calling SvPOK fixes this. |
|
|
1428 | * But it doesn't fix it, so try another workaround, call SvPV_nolen |
|
|
1429 | * and hope for the best. |
|
|
1430 | * Damnit, SvPV_nolen still trips over yet another assertion. This |
|
|
1431 | * assertion business is seriously broken, try yet another workaround |
|
|
1432 | * for the broken -DDEBUGGING. |
1423 | */ |
1433 | */ |
1424 | SvPOK (string); |
1434 | #ifdef DEBUGGING |
|
|
1435 | offset = SvOK (string) ? sv_len (string) : 0; |
|
|
1436 | #else |
|
|
1437 | offset = SvCUR (string); |
|
|
1438 | #endif |
1425 | |
1439 | |
1426 | if (SvCUR (string) > json->max_size && json->max_size) |
1440 | if (offset > json->max_size && json->max_size) |
1427 | croak ("attempted decode of JSON text of %lu bytes size, but max_size is set to %lu", |
1441 | croak ("attempted decode of JSON text of %lu bytes size, but max_size is set to %lu", |
1428 | (unsigned long)SvCUR (string), (unsigned long)json->max_size); |
1442 | (unsigned long)SvCUR (string), (unsigned long)json->max_size); |
1429 | |
1443 | |
1430 | if (json->flags & F_UTF8) |
1444 | if (json->flags & F_UTF8) |
1431 | sv_utf8_downgrade (string, 0); |
1445 | sv_utf8_downgrade (string, 0); |
… | |
… | |
1598 | croak (ERR_NESTING_EXCEEDED); |
1612 | croak (ERR_NESTING_EXCEEDED); |
1599 | break; |
1613 | break; |
1600 | |
1614 | |
1601 | case ']': |
1615 | case ']': |
1602 | case '}': |
1616 | case '}': |
1603 | if (!--self->incr_nest) |
1617 | if (--self->incr_nest <= 0) |
1604 | goto interrupt; |
1618 | goto interrupt; |
1605 | } |
1619 | } |
1606 | } |
1620 | } |
1607 | } |
1621 | } |
1608 | |
1622 | |