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.36 by root, Sat Nov 30 17:37:45 2013 UTC vs.
Revision 1.39 by root, Sun Dec 1 14:45:03 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
104#define F_VALIDATE_UTF8 0x00000020UL
103 105
104#define INIT_SIZE 32 // initial scalar size to be allocated 106#define INIT_SIZE 32 // initial scalar size to be allocated
105 107
106#define SB do { 108#define SB do {
107#define SE } while (0) 109#define SE } while (0)
735 I32 len = decode_uint (dec); 737 I32 len = decode_uint (dec);
736 char *key = (char *)dec->cur; 738 char *key = (char *)dec->cur;
737 739
738 dec->cur += len; 740 dec->cur += len;
739 741
740 if (ecb_expect_false (dec->stringref))
741 av_push (dec->stringref, newSVpvn (key, len));
742
743 hv_store (hv, key, len, decode_sv (dec), 0); 742 hv_store (hv, key, len, decode_sv (dec), 0);
744 743
745 return; 744 return;
746 } 745 }
747 else if (ecb_expect_true ((*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8)) 746 else if (ecb_expect_true ((*dec->cur - MAJOR_TEXT) <= LENGTH_EXT8))
749 I32 len = decode_uint (dec); 748 I32 len = decode_uint (dec);
750 char *key = (char *)dec->cur; 749 char *key = (char *)dec->cur;
751 750
752 dec->cur += len; 751 dec->cur += len;
753 752
754 if (ecb_expect_false (dec->stringref)) 753 if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
755 av_push (dec->stringref, newSVpvn_utf8 (key, len, 1)); 754 if (!is_utf8_string (key, len))
755 ERR ("corrupted CBOR data (invalid UTF-8 in map key)");
756 756
757 hv_store (hv, key, -len, decode_sv (dec), 0); 757 hv_store (hv, key, -len, decode_sv (dec), 0);
758 758
759 return; 759 return;
760 } 760 }
762 SV *k = decode_sv (dec); 762 SV *k = decode_sv (dec);
763 SV *v = decode_sv (dec); 763 SV *v = decode_sv (dec);
764 764
765 hv_store_ent (hv, k, v, 0); 765 hv_store_ent (hv, k, v, 0);
766 SvREFCNT_dec (k); 766 SvREFCNT_dec (k);
767
768fail:
769 ;
767} 770}
768 771
769static SV * 772static SV *
770decode_hv (dec_t *dec) 773decode_hv (dec_t *dec)
771{ 774{
853 && SvCUR (sv) >= minimum_string_length (AvFILLp (dec->stringref) + 1)) 856 && SvCUR (sv) >= minimum_string_length (AvFILLp (dec->stringref) + 1))
854 av_push (dec->stringref, SvREFCNT_inc_NN (sv)); 857 av_push (dec->stringref, SvREFCNT_inc_NN (sv));
855 } 858 }
856 859
857 if (utf8) 860 if (utf8)
861 {
862 if (ecb_expect_false (dec->cbor.flags & F_VALIDATE_UTF8))
863 if (!is_utf8_string (SvPVX (sv), SvCUR (sv)))
864 ERR ("corrupted CBOR data (invalid UTF-8 in text string)");
865
858 SvUTF8_on (sv); 866 SvUTF8_on (sv);
867 }
859 868
860 return sv; 869 return sv;
861 870
862fail: 871fail:
863 SvREFCNT_dec (sv); 872 SvREFCNT_dec (sv);
912 case CBOR_TAG_VALUE_SHAREABLE: 921 case CBOR_TAG_VALUE_SHAREABLE:
913 { 922 {
914 if (ecb_expect_false (!dec->shareable)) 923 if (ecb_expect_false (!dec->shareable))
915 dec->shareable = (AV *)sv_2mortal ((SV *)newAV ()); 924 dec->shareable = (AV *)sv_2mortal ((SV *)newAV ());
916 925
926 if (dec->cbor.flags & F_ALLOW_CYCLES)
927 {
917 sv = newSV (0); 928 sv = newSV (0);
918 av_push (dec->shareable, SvREFCNT_inc_NN (sv)); 929 av_push (dec->shareable, SvREFCNT_inc_NN (sv));
919 930
920 SV *osv = decode_sv (dec); 931 SV *osv = decode_sv (dec);
921 sv_setsv (sv, osv); 932 sv_setsv (sv, osv);
922 SvREFCNT_dec_NN (osv); 933 SvREFCNT_dec_NN (osv);
934 }
935 else
936 {
937 av_push (dec->shareable, &PL_sv_undef);
938 int idx = AvFILLp (dec->shareable);
939 sv = decode_sv (dec);
940 av_store (dec->shareable, idx, SvREFCNT_inc_NN (sv));
941 }
923 } 942 }
924 break; 943 break;
925 944
926 case CBOR_TAG_VALUE_SHAREDREF: 945 case CBOR_TAG_VALUE_SHAREDREF:
927 { 946 {
932 951
933 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable)) 952 if (!dec->shareable || (int)idx > AvFILLp (dec->shareable))
934 ERR ("corrupted CBOR data (sharedref index out of bounds)"); 953 ERR ("corrupted CBOR data (sharedref index out of bounds)");
935 954
936 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]); 955 sv = SvREFCNT_inc_NN (AvARRAY (dec->shareable)[idx]);
956
957 if (sv == &PL_sv_undef)
958 ERR ("cyclic CBOR data structure found, but allow_cycles is not enabled");
937 } 959 }
938 break; 960 break;
939 961
940 case CBOR_TAG_PERL_OBJECT: 962 case CBOR_TAG_PERL_OBJECT:
941 { 963 {
1149 if (dec.cur != dec.end && !dec.err) 1171 if (dec.cur != dec.end && !dec.err)
1150 dec.err = "garbage after CBOR object"; 1172 dec.err = "garbage after CBOR object";
1151 1173
1152 if (dec.err) 1174 if (dec.err)
1153 { 1175 {
1176 if (dec.shareable)
1177 {
1178 // need to break cyclic links, which whould all be in shareable
1179 int i;
1180 SV **svp;
1181
1182 for (i = av_len (dec.shareable) + 1; i--; )
1183 if ((svp = av_fetch (dec.shareable, i, 0)))
1184 sv_setsv (*svp, &PL_sv_undef);
1185 }
1186
1154 SvREFCNT_dec (sv); 1187 SvREFCNT_dec (sv);
1155 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur); 1188 croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur);
1156 } 1189 }
1157 1190
1158 sv = sv_2mortal (sv); 1191 sv = sv_2mortal (sv);
1207void shrink (CBOR *self, int enable = 1) 1240void shrink (CBOR *self, int enable = 1)
1208 ALIAS: 1241 ALIAS:
1209 shrink = F_SHRINK 1242 shrink = F_SHRINK
1210 allow_unknown = F_ALLOW_UNKNOWN 1243 allow_unknown = F_ALLOW_UNKNOWN
1211 allow_sharing = F_ALLOW_SHARING 1244 allow_sharing = F_ALLOW_SHARING
1245 allow_cycles = F_ALLOW_CYCLES
1212 pack_strings = F_PACK_STRINGS 1246 pack_strings = F_PACK_STRINGS
1247 validate_utf8 = F_VALIDATE_UTF8
1213 PPCODE: 1248 PPCODE:
1214{ 1249{
1215 if (enable) 1250 if (enable)
1216 self->flags |= ix; 1251 self->flags |= ix;
1217 else 1252 else
1223void get_shrink (CBOR *self) 1258void get_shrink (CBOR *self)
1224 ALIAS: 1259 ALIAS:
1225 get_shrink = F_SHRINK 1260 get_shrink = F_SHRINK
1226 get_allow_unknown = F_ALLOW_UNKNOWN 1261 get_allow_unknown = F_ALLOW_UNKNOWN
1227 get_allow_sharing = F_ALLOW_SHARING 1262 get_allow_sharing = F_ALLOW_SHARING
1263 get_allow_cycles = F_ALLOW_CYCLES
1228 get_pack_strings = F_PACK_STRINGS 1264 get_pack_strings = F_PACK_STRINGS
1265 get_validate_utf8 = F_VALIDATE_UTF8
1229 PPCODE: 1266 PPCODE:
1230 XPUSHs (boolSV (self->flags & ix)); 1267 XPUSHs (boolSV (self->flags & ix));
1231 1268
1232void max_depth (CBOR *self, U32 max_depth = 0x80000000UL) 1269void max_depth (CBOR *self, U32 max_depth = 0x80000000UL)
1233 PPCODE: 1270 PPCODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines