--- JSON-XS/XS.xs 2007/06/25 04:08:17 1.44 +++ JSON-XS/XS.xs 2007/06/25 06:57:42 1.45 @@ -30,8 +30,11 @@ #define F_CONV_BLESSED 0x00000800UL // NYI #define F_MAXDEPTH 0xf8000000UL #define S_MAXDEPTH 27 +#define F_MAXSIZE 0x01f00000UL +#define S_MAXSIZE 20 #define DEC_DEPTH(flags) (1UL << ((flags & F_MAXDEPTH) >> S_MAXDEPTH)) +#define DEC_SIZE(flags) (1UL << ((flags & F_MAXSIZE ) >> S_MAXSIZE )) #define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER #define F_DEFAULT (9UL << S_MAXDEPTH) @@ -1135,6 +1138,10 @@ SvGETMAGIC (string); SvUPGRADE (string, SVt_PV); + if (flags & F_MAXSIZE && SvCUR (string) > DEC_SIZE (flags)) + croak ("attempted decode of JSON text of %lu bytes size, but max_size is set to %lu", + (unsigned long)SvCUR (string), (unsigned long)DEC_SIZE (flags)); + if (flags & F_UTF8) sv_utf8_downgrade (string, 0); else @@ -1275,6 +1282,25 @@ RETVAL = newSVsv (self); } + OUTPUT: + RETVAL + +SV *max_size (SV *self, UV max_size = 0) + CODE: +{ + UV *uv = SvJSON (self); + UV log2 = 0; + + if (max_size > 0x80000000UL) max_size = 0x80000000UL; + if (max_size == 1) max_size = 2; + + while ((1UL << log2) < max_size) + ++log2; + + *uv = *uv & ~F_MAXSIZE | (log2 << S_MAXSIZE); + + RETVAL = newSVsv (self); +} OUTPUT: RETVAL