--- CBOR-XS/XS.xs 2016/04/24 20:08:41 1.54 +++ CBOR-XS/XS.xs 2016/11/25 12:16:12 1.57 @@ -667,9 +667,9 @@ #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE -#define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") +#define WANT(len) if (ecb_expect_false ((UV)(dec->end - dec->cur) < (UV)len)) ERR ("unexpected end of CBOR data") -#define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) +#define DEC_INC_DEPTH if (ecb_expect_false (++dec->depth > dec->cbor.max_depth)) ERR (ERR_NESTING_EXCEEDED) #define DEC_DEC_DEPTH --dec->depth static UV @@ -756,7 +756,7 @@ } else { - int i, len = decode_uint (dec); + UV i, len = decode_uint (dec); WANT (len); // complexity check for av_fill - need at least one byte per value, do not allow supersize arrays av_fill (av, len - 1); @@ -783,7 +783,7 @@ if (ecb_expect_true (!dec->stringref)) if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8)) { - I32 len = decode_uint (dec); + STRLEN len = decode_uint (dec); char *key = (char *)dec->cur; WANT (len); @@ -795,7 +795,7 @@ } else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) { - I32 len = decode_uint (dec); + STRLEN len = decode_uint (dec); char *key = (char *)dec->cur; WANT (len); @@ -846,7 +846,9 @@ } else { - int pairs = decode_uint (dec); + UV pairs = decode_uint (dec); + + WANT (pairs); // complexity check - need at least one byte per value, do not allow supersize hashes while (pairs--) decode_he (dec, hv); @@ -944,14 +946,16 @@ case CBOR_TAG_STRINGREF_NAMESPACE: { - ENTER; SAVETMPS; + // do nmot use SAVETMPS/FREETMPS, as these will + // erase mortalised caches, e.g. "shareable" + ENTER; SAVESPTR (dec->stringref); dec->stringref = (AV *)sv_2mortal ((SV *)newAV ()); sv = decode_sv (dec); - FREETMPS; LEAVE; + LEAVE; } break; @@ -1394,6 +1398,8 @@ sv_cbor = newSVpv ("CBOR", 0); SvREADONLY_on (sv_cbor); + + assert (("STRLEN must be an unsigned type", 0 <= (STRLEN)-1)); } PROTOTYPES: DISABLE