--- CBOR-XS/XS.xs 2013/11/28 12:08:07 1.32 +++ CBOR-XS/XS.xs 2013/11/30 15:23:59 1.33 @@ -329,28 +329,6 @@ { SvGETMAGIC (sv); - if (ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING) - && ecb_expect_false (SvREFCNT (sv) > 1)) - { - if (!enc->shareable) - enc->shareable = (HV *)sv_2mortal ((SV *)newHV ()); - - SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1); - - if (SvOK (*svp)) - { - encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF); - encode_uint (enc, 0x00, SvUV (*svp)); - return; - } - else - { - sv_setuv (*svp, enc->shareable_idx); - ++enc->shareable_idx; - encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE); - } - } - svtype svt = SvTYPE (sv); if (ecb_expect_false (SvOBJECT (sv))) @@ -442,6 +420,28 @@ encode_av (enc, (AV *)sv); else { + if (ecb_expect_false (SvREFCNT (sv) > 1) + && ecb_expect_false (enc->cbor.flags & F_ALLOW_SHARING)) + { + if (!enc->shareable) + enc->shareable = (HV *)sv_2mortal ((SV *)newHV ()); + + SV **svp = hv_fetch (enc->shareable, (char *)&sv, sizeof (sv), 1); + + if (SvOK (*svp)) + { + encode_tag (enc, CBOR_TAG_VALUE_SHAREDREF); + encode_uint (enc, 0x00, SvUV (*svp)); + return; + } + else + { + sv_setuv (*svp, enc->shareable_idx); + ++enc->shareable_idx; + encode_tag (enc, CBOR_TAG_VALUE_SHAREABLE); + } + } + encode_tag (enc, CBOR_TAG_INDIRECTION); encode_sv (enc, sv); } @@ -755,22 +755,31 @@ if ((*dec->cur & 31) == 31) { + // indefinite length strings ++dec->cur; + unsigned char major = *dec->cur & 0xe0; + sv = newSVpvn ("", 0); - // not very fast, and certainly not robust against illegal input for (;;) { WANT (1); - if (*dec->cur == (0xe0 | 31)) - { - ++dec->cur; - break; - } - - sv_catsv (sv, decode_sv (dec)); + if ((*dec->cur ^ major) >= 31) + if (*dec->cur == (0xe0 | 31)) + { + ++dec->cur; + break; + } + else + ERR ("corrupted CBOR data (invalid chunks in indefinite length string)"); + + STRLEN len = decode_uint (dec); + + WANT (len); + sv_catpvn (sv, dec->cur, len); + dec->cur += len; } } else