… | |
… | |
667 | |
667 | |
668 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
668 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
669 | |
669 | |
670 | #define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") |
670 | #define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") |
671 | |
671 | |
672 | #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) |
672 | #define DEC_INC_DEPTH if (ecb_expect_false (++dec->depth > dec->cbor.max_depth)) ERR (ERR_NESTING_EXCEEDED) |
673 | #define DEC_DEC_DEPTH --dec->depth |
673 | #define DEC_DEC_DEPTH --dec->depth |
674 | |
674 | |
675 | static UV |
675 | static UV |
676 | decode_uint (dec_t *dec) |
676 | decode_uint (dec_t *dec) |
677 | { |
677 | { |
… | |
… | |
781 | // byte or utf-8 strings as keys, but only when !stringref |
781 | // byte or utf-8 strings as keys, but only when !stringref |
782 | |
782 | |
783 | if (ecb_expect_true (!dec->stringref)) |
783 | if (ecb_expect_true (!dec->stringref)) |
784 | if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8)) |
784 | if (ecb_expect_true ((U8)(*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8)) |
785 | { |
785 | { |
786 | I32 len = decode_uint (dec); |
786 | STRLEN len = decode_uint (dec); |
787 | char *key = (char *)dec->cur; |
787 | char *key = (char *)dec->cur; |
788 | |
788 | |
789 | WANT (len); |
789 | WANT (len); |
790 | dec->cur += len; |
790 | dec->cur += len; |
791 | |
791 | |
… | |
… | |
793 | |
793 | |
794 | return; |
794 | return; |
795 | } |
795 | } |
796 | else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) |
796 | else if (ecb_expect_true ((U8)(*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) |
797 | { |
797 | { |
798 | I32 len = decode_uint (dec); |
798 | STRLEN len = decode_uint (dec); |
799 | char *key = (char *)dec->cur; |
799 | char *key = (char *)dec->cur; |
800 | |
800 | |
801 | WANT (len); |
801 | WANT (len); |
802 | dec->cur += len; |
802 | dec->cur += len; |
803 | |
803 | |
… | |
… | |
942 | sv = newRV_noinc (decode_sv (dec)); |
942 | sv = newRV_noinc (decode_sv (dec)); |
943 | break; |
943 | break; |
944 | |
944 | |
945 | case CBOR_TAG_STRINGREF_NAMESPACE: |
945 | case CBOR_TAG_STRINGREF_NAMESPACE: |
946 | { |
946 | { |
|
|
947 | // do nmot use SAVETMPS/FREETMPS, as these will |
|
|
948 | // erase mortalised caches, e.g. "shareable" |
947 | ENTER; SAVETMPS; |
949 | ENTER; |
948 | |
950 | |
949 | SAVESPTR (dec->stringref); |
951 | SAVESPTR (dec->stringref); |
950 | dec->stringref = (AV *)sv_2mortal ((SV *)newAV ()); |
952 | dec->stringref = (AV *)sv_2mortal ((SV *)newAV ()); |
951 | |
953 | |
952 | sv = decode_sv (dec); |
954 | sv = decode_sv (dec); |
953 | |
955 | |
954 | FREETMPS; LEAVE; |
956 | LEAVE; |
955 | } |
957 | } |
956 | break; |
958 | break; |
957 | |
959 | |
958 | case CBOR_TAG_STRINGREF: |
960 | case CBOR_TAG_STRINGREF: |
959 | { |
961 | { |
… | |
… | |
1392 | |
1394 | |
1393 | default_filter = newSVpv ("CBOR::XS::default_filter", 0); |
1395 | default_filter = newSVpv ("CBOR::XS::default_filter", 0); |
1394 | |
1396 | |
1395 | sv_cbor = newSVpv ("CBOR", 0); |
1397 | sv_cbor = newSVpv ("CBOR", 0); |
1396 | SvREADONLY_on (sv_cbor); |
1398 | SvREADONLY_on (sv_cbor); |
|
|
1399 | |
|
|
1400 | assert (("STRLEN must be an unsigned type", 0 <= (STRLEN)-1)); |
1397 | } |
1401 | } |
1398 | |
1402 | |
1399 | PROTOTYPES: DISABLE |
1403 | PROTOTYPES: DISABLE |
1400 | |
1404 | |
1401 | void CLONE (...) |
1405 | void CLONE (...) |