--- CBOR-XS/XS.xs 2013/11/30 17:37:45 1.36 +++ CBOR-XS/XS.xs 2013/11/30 18:13:53 1.37 @@ -99,7 +99,8 @@ #define F_SHRINK 0x00000001UL #define F_ALLOW_UNKNOWN 0x00000002UL #define F_ALLOW_SHARING 0x00000004UL -#define F_PACK_STRINGS 0x00000008UL +#define F_ALLOW_CYCLES 0x00000008UL +#define F_PACK_STRINGS 0x00000010UL #define INIT_SIZE 32 // initial scalar size to be allocated @@ -914,12 +915,22 @@ if (ecb_expect_false (!dec->shareable)) dec->shareable = (AV *)sv_2mortal ((SV *)newAV ()); - sv = newSV (0); - av_push (dec->shareable, SvREFCNT_inc_NN (sv)); + if (dec->cbor.flags & F_ALLOW_CYCLES) + { + sv = newSV (0); + av_push (dec->shareable, SvREFCNT_inc_NN (sv)); - SV *osv = decode_sv (dec); - sv_setsv (sv, osv); - SvREFCNT_dec_NN (osv); + SV *osv = decode_sv (dec); + sv_setsv (sv, osv); + SvREFCNT_dec_NN (osv); + } + else + { + av_push (dec->shareable, &PL_sv_undef); + int idx = AvFILLp (dec->shareable); + sv = decode_sv (dec); + av_store (dec->shareable, idx, SvREFCNT_inc_NN (sv)); + } } break; @@ -934,6 +945,9 @@ ERR ("corrupted CBOR data (sharedref index out of bounds)"); sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]); + + if (sv == &PL_sv_undef) + ERR ("cyclic CBOR data structure found, but allow_cycles is not enabled"); } break; @@ -1209,6 +1223,7 @@ shrink = F_SHRINK allow_unknown = F_ALLOW_UNKNOWN allow_sharing = F_ALLOW_SHARING + allow_cycles = F_ALLOW_CYCLES pack_strings = F_PACK_STRINGS PPCODE: { @@ -1225,6 +1240,7 @@ get_shrink = F_SHRINK get_allow_unknown = F_ALLOW_UNKNOWN get_allow_sharing = F_ALLOW_SHARING + get_allow_cycles = F_ALLOW_CYCLES get_pack_strings = F_PACK_STRINGS PPCODE: XPUSHs (boolSV (self->flags & ix));