ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/XS.xs
(Generate patch)

Comparing CBOR-XS/XS.xs (file contents):
Revision 1.35 by root, Sat Nov 30 17:19:34 2013 UTC vs.
Revision 1.37 by root, Sat Nov 30 18:13:53 2013 UTC

97}; 97};
98 98
99#define F_SHRINK 0x00000001UL 99#define F_SHRINK 0x00000001UL
100#define F_ALLOW_UNKNOWN 0x00000002UL 100#define F_ALLOW_UNKNOWN 0x00000002UL
101#define F_ALLOW_SHARING 0x00000004UL 101#define F_ALLOW_SHARING 0x00000004UL
102#define F_ALLOW_CYCLES 0x00000008UL
102#define F_PACK_STRINGS 0x00000008UL 103#define F_PACK_STRINGS 0x00000010UL
103 104
104#define INIT_SIZE 32 // initial scalar size to be allocated 105#define INIT_SIZE 32 // initial scalar size to be allocated
105 106
106#define SB do { 107#define SB do {
107#define SE } while (0) 108#define SE } while (0)
228{ 229{
229 need (enc, 9); 230 need (enc, 9);
230 231
231 if (ecb_expect_true (len < LENGTH_EXT1)) 232 if (ecb_expect_true (len < LENGTH_EXT1))
232 *enc->cur++ = major | len; 233 *enc->cur++ = major | len;
233 else if (ecb_expect_true (len <= 0xff)) 234 else if (ecb_expect_true (len <= 0xffU))
234 { 235 {
235 *enc->cur++ = major | LENGTH_EXT1; 236 *enc->cur++ = major | LENGTH_EXT1;
236 *enc->cur++ = len; 237 *enc->cur++ = len;
237 } 238 }
238 else if (len <= 0xffff) 239 else if (len <= 0xffffU)
239 { 240 {
240 *enc->cur++ = major | LENGTH_EXT2; 241 *enc->cur++ = major | LENGTH_EXT2;
241 *enc->cur++ = len >> 8; 242 *enc->cur++ = len >> 8;
242 *enc->cur++ = len; 243 *enc->cur++ = len;
243 } 244 }
244 else if (len <= 0xffffffff) 245 else if (len <= 0xffffffffU)
245 { 246 {
246 *enc->cur++ = major | LENGTH_EXT4; 247 *enc->cur++ = major | LENGTH_EXT4;
247 *enc->cur++ = len >> 24; 248 *enc->cur++ = len >> 24;
248 *enc->cur++ = len >> 16; 249 *enc->cur++ = len >> 16;
249 *enc->cur++ = len >> 8; 250 *enc->cur++ = len >> 8;
627 U8 m = *dec->cur & MINOR_MASK; 628 U8 m = *dec->cur & MINOR_MASK;
628 ++dec->cur; 629 ++dec->cur;
629 630
630 if (ecb_expect_true (m < LENGTH_EXT1)) 631 if (ecb_expect_true (m < LENGTH_EXT1))
631 return m; 632 return m;
632 633 else if (ecb_expect_true (m == LENGTH_EXT1))
633 switch (m)
634 { 634 {
635 case LENGTH_EXT1:
636 WANT (1); 635 WANT (1);
637 dec->cur += 1; 636 dec->cur += 1;
638 return dec->cur[-1]; 637 return dec->cur[-1];
639 638 }
640 case LENGTH_EXT2: 639 else if (ecb_expect_true (m == LENGTH_EXT2))
640 {
641 WANT (2); 641 WANT (2);
642 dec->cur += 2; 642 dec->cur += 2;
643 return (((UV)dec->cur[-2]) << 8) 643 return (((UV)dec->cur[-2]) << 8)
644 | ((UV)dec->cur[-1]); 644 | ((UV)dec->cur[-1]);
645 645 }
646 case LENGTH_EXT4: 646 else if (ecb_expect_true (m == LENGTH_EXT4))
647 {
647 WANT (4); 648 WANT (4);
648 dec->cur += 4; 649 dec->cur += 4;
649 return (((UV)dec->cur[-4]) << 24) 650 return (((UV)dec->cur[-4]) << 24)
650 | (((UV)dec->cur[-3]) << 16) 651 | (((UV)dec->cur[-3]) << 16)
651 | (((UV)dec->cur[-2]) << 8) 652 | (((UV)dec->cur[-2]) << 8)
652 | ((UV)dec->cur[-1]); 653 | ((UV)dec->cur[-1]);
653 654 }
654 case LENGTH_EXT8: 655 else if (ecb_expect_true (m == LENGTH_EXT8))
656 {
655 WANT (8); 657 WANT (8);
656 dec->cur += 8; 658 dec->cur += 8;
657 659
658 return 660 return
659#if UVSIZE < 8 661#if UVSIZE < 8
660 0 662 0
661#else 663#else
662 (((UV)dec->cur[-8]) << 56) 664 (((UV)dec->cur[-8]) << 56)
663 | (((UV)dec->cur[-7]) << 48) 665 | (((UV)dec->cur[-7]) << 48)
664 | (((UV)dec->cur[-6]) << 40) 666 | (((UV)dec->cur[-6]) << 40)
665 | (((UV)dec->cur[-5]) << 32) 667 | (((UV)dec->cur[-5]) << 32)
666#endif 668#endif
667 | (((UV)dec->cur[-4]) << 24) 669 | (((UV)dec->cur[-4]) << 24)
668 | (((UV)dec->cur[-3]) << 16) 670 | (((UV)dec->cur[-3]) << 16)
669 | (((UV)dec->cur[-2]) << 8) 671 | (((UV)dec->cur[-2]) << 8)
670 | ((UV)dec->cur[-1]); 672 | ((UV)dec->cur[-1]);
671 673 }
672 default: 674 else
673 ERR ("corrupted CBOR data (unsupported integer minor encoding)"); 675 ERR ("corrupted CBOR data (unsupported integer minor encoding)");
674 }
675 676
676fail: 677fail:
677 return 0; 678 return 0;
678} 679}
679 680
705 } 706 }
706 else 707 else
707 { 708 {
708 int i, len = decode_uint (dec); 709 int i, len = decode_uint (dec);
709 710
711 WANT (len); // complexity check for av_fill - need at least one byte per value, do not allow supersize arrays
710 av_fill (av, len - 1); 712 av_fill (av, len - 1);
711 713
712 for (i = 0; i < len; ++i) 714 for (i = 0; i < len; ++i)
713 AvARRAY (av)[i] = decode_sv (dec); 715 AvARRAY (av)[i] = decode_sv (dec);
714 } 716 }
727{ 729{
728 // for speed reasons, we specialcase single-string 730 // for speed reasons, we specialcase single-string
729 // byte or utf-8 strings as keys, but only when !stringref 731 // byte or utf-8 strings as keys, but only when !stringref
730 732
731 if (ecb_expect_true (!dec->stringref)) 733 if (ecb_expect_true (!dec->stringref))
732 if ((*dec->cur - MAJOR_BYTES) <= 27) 734 if (ecb_expect_true ((*dec->cur - MAJOR_BYTES) <= LENGTH_EXT8))
733 { 735 {
734 I32 len = decode_uint (dec); 736 I32 len = decode_uint (dec);
735 char *key = (char *)dec->cur; 737 char *key = (char *)dec->cur;
736 738
737 dec->cur += len; 739 dec->cur += len;
741 743
742 hv_store (hv, key, len, decode_sv (dec), 0); 744 hv_store (hv, key, len, decode_sv (dec), 0);
743 745
744 return; 746 return;
745 } 747 }
746 else if ((*dec->cur - MAJOR_TEXT) <= 27) 748 else if (ecb_expect_true ((*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8))
747 { 749 {
748 I32 len = decode_uint (dec); 750 I32 len = decode_uint (dec);
749 char *key = (char *)dec->cur; 751 char *key = (char *)dec->cur;
750 752
751 dec->cur += len; 753 dec->cur += len;
911 case CBOR_TAG_VALUE_SHAREABLE: 913 case CBOR_TAG_VALUE_SHAREABLE:
912 { 914 {
913 if (ecb_expect_false (!dec->shareable)) 915 if (ecb_expect_false (!dec->shareable))
914 dec->shareable = (AV *)sv_2mortal ((SV *)newAV ()); 916 dec->shareable = (AV *)sv_2mortal ((SV *)newAV ());
915 917
918 if (dec->cbor.flags & F_ALLOW_CYCLES)
919 {
916 sv = newSV (0); 920 sv = newSV (0);
917 av_push (dec->shareable, SvREFCNT_inc_NN (sv)); 921 av_push (dec->shareable, SvREFCNT_inc_NN (sv));
918 922
919 SV *osv = decode_sv (dec); 923 SV *osv = decode_sv (dec);
920 sv_setsv (sv, osv); 924 sv_setsv (sv, osv);
921 SvREFCNT_dec_NN (osv); 925 SvREFCNT_dec_NN (osv);
926 }
927 else
928 {
929 av_push (dec->shareable, &PL_sv_undef);
930 int idx = AvFILLp (dec->shareable);
931 sv = decode_sv (dec);
932 av_store (dec->shareable, idx, SvREFCNT_inc_NN (sv));
933 }
922 } 934 }
923 break; 935 break;
924 936
925 case CBOR_TAG_VALUE_SHAREDREF: 937 case CBOR_TAG_VALUE_SHAREDREF:
926 { 938 {
931 943
932 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable)) 944 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable))
933 ERR ("corrupted CBOR data (sharedref index out of bounds)"); 945 ERR ("corrupted CBOR data (sharedref index out of bounds)");
934 946
935 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]); 947 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]);
948
949 if (sv == &PL_sv_undef)
950 ERR ("cyclic CBOR data structure found, but allow_cycles is not enabled");
936 } 951 }
937 break; 952 break;
938 953
939 case CBOR_TAG_PERL_OBJECT: 954 case CBOR_TAG_PERL_OBJECT:
940 { 955 {
1206void shrink (CBOR *self, int enable = 1) 1221void shrink (CBOR *self, int enable = 1)
1207 ALIAS: 1222 ALIAS:
1208 shrink = F_SHRINK 1223 shrink = F_SHRINK
1209 allow_unknown = F_ALLOW_UNKNOWN 1224 allow_unknown = F_ALLOW_UNKNOWN
1210 allow_sharing = F_ALLOW_SHARING 1225 allow_sharing = F_ALLOW_SHARING
1226 allow_cycles = F_ALLOW_CYCLES
1211 pack_strings = F_PACK_STRINGS 1227 pack_strings = F_PACK_STRINGS
1212 PPCODE: 1228 PPCODE:
1213{ 1229{
1214 if (enable) 1230 if (enable)
1215 self->flags |= ix; 1231 self->flags |= ix;
1222void get_shrink (CBOR *self) 1238void get_shrink (CBOR *self)
1223 ALIAS: 1239 ALIAS:
1224 get_shrink = F_SHRINK 1240 get_shrink = F_SHRINK
1225 get_allow_unknown = F_ALLOW_UNKNOWN 1241 get_allow_unknown = F_ALLOW_UNKNOWN
1226 get_allow_sharing = F_ALLOW_SHARING 1242 get_allow_sharing = F_ALLOW_SHARING
1243 get_allow_cycles = F_ALLOW_CYCLES
1227 get_pack_strings = F_PACK_STRINGS 1244 get_pack_strings = F_PACK_STRINGS
1228 PPCODE: 1245 PPCODE:
1229 XPUSHs (boolSV (self->flags & ix)); 1246 XPUSHs (boolSV (self->flags & ix));
1230 1247
1231void max_depth (CBOR *self, U32 max_depth = 0x80000000UL) 1248void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1288 cbor_free (self); 1305 cbor_free (self);
1289 1306
1290PROTOTYPES: ENABLE 1307PROTOTYPES: ENABLE
1291 1308
1292void encode_cbor (SV *scalar) 1309void encode_cbor (SV *scalar)
1310 ALIAS:
1311 encode_cbor = 0
1312 encode_cbor_sharing = F_ALLOW_SHARING
1293 PPCODE: 1313 PPCODE:
1294{ 1314{
1295 CBOR cbor; 1315 CBOR cbor;
1296 cbor_init (&cbor); 1316 cbor_init (&cbor);
1317 cbor.flags |= ix;
1297 PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN; 1318 PUTBACK; scalar = encode_cbor (scalar, &cbor); SPAGAIN;
1298 XPUSHs (scalar); 1319 XPUSHs (scalar);
1299} 1320}
1300 1321
1301void decode_cbor (SV *cborstr) 1322void decode_cbor (SV *cborstr)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines