… | |
… | |
9 | #include <limits.h> |
9 | #include <limits.h> |
10 | #include <float.h> |
10 | #include <float.h> |
11 | |
11 | |
12 | #include "ecb.h" |
12 | #include "ecb.h" |
13 | |
13 | |
14 | #if defined(__BORLANDC__) || defined(_MSC_VER) |
|
|
15 | # define snprintf _snprintf // C compilers have this in stdio.h |
|
|
16 | #endif |
|
|
17 | |
|
|
18 | #define F_SHRINK 0x00000200UL |
14 | #define F_SHRINK 0x00000200UL |
19 | #define F_ALLOW_UNKNOWN 0x00002000UL |
15 | #define F_ALLOW_UNKNOWN 0x00002000UL |
20 | |
16 | |
21 | #define INIT_SIZE 32 // initial scalar size to be allocated |
17 | #define INIT_SIZE 32 // initial scalar size to be allocated |
22 | |
18 | |
23 | #define SB do { |
19 | #define SB do { |
24 | #define SE } while (0) |
20 | #define SE } while (0) |
25 | |
|
|
26 | #if __GNUC__ >= 3 |
|
|
27 | # define expect(expr,value) __builtin_expect ((expr), (value)) |
|
|
28 | # define INLINE static inline |
|
|
29 | #else |
|
|
30 | # define expect(expr,value) (expr) |
|
|
31 | # define INLINE static |
|
|
32 | #endif |
|
|
33 | |
|
|
34 | #define expect_false(expr) expect ((expr) != 0, 0) |
|
|
35 | #define expect_true(expr) expect ((expr) != 0, 1) |
|
|
36 | |
21 | |
37 | #define IN_RANGE_INC(type,val,beg,end) \ |
22 | #define IN_RANGE_INC(type,val,beg,end) \ |
38 | ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \ |
23 | ((unsigned type)((unsigned type)(val) - (unsigned type)(beg)) \ |
39 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
24 | <= (unsigned type)((unsigned type)(end) - (unsigned type)(beg))) |
40 | |
25 | |
… | |
… | |
58 | |
43 | |
59 | SV *cb_object; |
44 | SV *cb_object; |
60 | HV *cb_sk_object; |
45 | HV *cb_sk_object; |
61 | } CBOR; |
46 | } CBOR; |
62 | |
47 | |
63 | INLINE void |
48 | ecb_inline void |
64 | cbor_init (CBOR *cbor) |
49 | cbor_init (CBOR *cbor) |
65 | { |
50 | { |
66 | Zero (cbor, 1, CBOR); |
51 | Zero (cbor, 1, CBOR); |
67 | cbor->max_depth = 512; |
52 | cbor->max_depth = 512; |
68 | } |
53 | } |
69 | |
54 | |
70 | ///////////////////////////////////////////////////////////////////////////// |
55 | ///////////////////////////////////////////////////////////////////////////// |
71 | // utility functions |
56 | // utility functions |
72 | |
57 | |
73 | INLINE SV * |
58 | ecb_inline SV * |
74 | get_bool (const char *name) |
59 | get_bool (const char *name) |
75 | { |
60 | { |
76 | SV *sv = get_sv (name, 1); |
61 | SV *sv = get_sv (name, 1); |
77 | |
62 | |
78 | SvREADONLY_on (sv); |
63 | SvREADONLY_on (sv); |
79 | SvREADONLY_on (SvRV (sv)); |
64 | SvREADONLY_on (SvRV (sv)); |
80 | |
65 | |
81 | return sv; |
66 | return sv; |
82 | } |
67 | } |
83 | |
68 | |
84 | INLINE void |
69 | ecb_inline void |
85 | shrink (SV *sv) |
70 | shrink (SV *sv) |
86 | { |
71 | { |
87 | sv_utf8_downgrade (sv, 1); |
72 | sv_utf8_downgrade (sv, 1); |
88 | |
73 | |
89 | if (SvLEN (sv) > SvCUR (sv) + 1) |
74 | if (SvLEN (sv) > SvCUR (sv) + 1) |
… | |
… | |
112 | SV *sv; // result scalar |
97 | SV *sv; // result scalar |
113 | CBOR cbor; |
98 | CBOR cbor; |
114 | U32 depth; // recursion level |
99 | U32 depth; // recursion level |
115 | } enc_t; |
100 | } enc_t; |
116 | |
101 | |
117 | INLINE void |
102 | ecb_inline void |
118 | need (enc_t *enc, STRLEN len) |
103 | need (enc_t *enc, STRLEN len) |
119 | { |
104 | { |
120 | if (expect_false (enc->cur + len >= enc->end)) |
105 | if (ecb_expect_false (enc->cur + len >= enc->end)) |
121 | { |
106 | { |
122 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
107 | STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); |
123 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
108 | SvGROW (enc->sv, cur + (len < (cur >> 2) ? cur >> 2 : len) + 1); |
124 | enc->cur = SvPVX (enc->sv) + cur; |
109 | enc->cur = SvPVX (enc->sv) + cur; |
125 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
110 | enc->end = SvPVX (enc->sv) + SvLEN (enc->sv) - 1; |
126 | } |
111 | } |
127 | } |
112 | } |
128 | |
113 | |
129 | INLINE void |
114 | ecb_inline void |
130 | encode_ch (enc_t *enc, char ch) |
115 | encode_ch (enc_t *enc, char ch) |
131 | { |
116 | { |
132 | need (enc, 1); |
117 | need (enc, 1); |
133 | *enc->cur++ = ch; |
118 | *enc->cur++ = ch; |
134 | } |
119 | } |
… | |
… | |
138 | { |
123 | { |
139 | need (enc, 9); |
124 | need (enc, 9); |
140 | |
125 | |
141 | if (len < 24) |
126 | if (len < 24) |
142 | *enc->cur++ = major | len; |
127 | *enc->cur++ = major | len; |
143 | else if (len < 0x100) |
128 | else if (len <= 0xff) |
144 | { |
129 | { |
145 | *enc->cur++ = major | 24; |
130 | *enc->cur++ = major | 24; |
146 | *enc->cur++ = len; |
131 | *enc->cur++ = len; |
147 | } |
132 | } |
148 | else if (len < 0x10000) |
133 | else if (len <= 0xffff) |
149 | { |
134 | { |
150 | *enc->cur++ = major | 25; |
135 | *enc->cur++ = major | 25; |
151 | *enc->cur++ = len >> 8; |
136 | *enc->cur++ = len >> 8; |
152 | *enc->cur++ = len; |
137 | *enc->cur++ = len; |
153 | } |
138 | } |
154 | else if (len < 0x100000000) |
139 | else if (len <= 0xffffffff) |
155 | { |
140 | { |
156 | *enc->cur++ = major | 26; |
141 | *enc->cur++ = major | 26; |
157 | *enc->cur++ = len >> 24; |
142 | *enc->cur++ = len >> 24; |
158 | *enc->cur++ = len >> 16; |
143 | *enc->cur++ = len >> 16; |
159 | *enc->cur++ = len >> 8; |
144 | *enc->cur++ = len >> 8; |
160 | *enc->cur++ = len; |
145 | *enc->cur++ = len; |
161 | } |
146 | } |
162 | else if (len) |
147 | else |
163 | { |
148 | { |
164 | *enc->cur++ = major | 27; |
149 | *enc->cur++ = major | 27; |
165 | *enc->cur++ = len >> 56; |
150 | *enc->cur++ = len >> 56; |
166 | *enc->cur++ = len >> 48; |
151 | *enc->cur++ = len >> 48; |
167 | *enc->cur++ = len >> 40; |
152 | *enc->cur++ = len >> 40; |
… | |
… | |
228 | if (HeKLEN (he) == HEf_SVKEY) |
213 | if (HeKLEN (he) == HEf_SVKEY) |
229 | encode_sv (enc, HeSVKEY (he)); |
214 | encode_sv (enc, HeSVKEY (he)); |
230 | else |
215 | else |
231 | encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); |
216 | encode_str (enc, HeKUTF8 (he), HeKEY (he), HeKLEN (he)); |
232 | |
217 | |
233 | encode_sv (enc, expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he)); |
218 | encode_sv (enc, ecb_expect_false (mg) ? hv_iterval (hv, he) : HeVAL (he)); |
234 | } |
219 | } |
235 | |
220 | |
236 | if (mg) |
221 | if (mg) |
237 | encode_ch (enc, 0xe0 | 31); |
222 | encode_ch (enc, 0xe0 | 31); |
238 | |
223 | |
… | |
… | |
246 | svtype svt; |
231 | svtype svt; |
247 | |
232 | |
248 | SvGETMAGIC (sv); |
233 | SvGETMAGIC (sv); |
249 | svt = SvTYPE (sv); |
234 | svt = SvTYPE (sv); |
250 | |
235 | |
251 | if (expect_false (SvOBJECT (sv))) |
236 | if (ecb_expect_false (SvOBJECT (sv))) |
252 | { |
237 | { |
253 | HV *stash = !CBOR_SLOW || cbor_boolean_stash |
238 | HV *stash = !CBOR_SLOW || cbor_boolean_stash |
254 | ? cbor_boolean_stash |
239 | ? cbor_boolean_stash |
255 | : gv_stashpv ("CBOR::XS::Boolean", 1); |
240 | : gv_stashpv ("CBOR::XS::Boolean", 1); |
256 | |
241 | |
… | |
… | |
332 | { |
317 | { |
333 | double nv = SvNVX (sv); |
318 | double nv = SvNVX (sv); |
334 | |
319 | |
335 | need (enc, 9); |
320 | need (enc, 9); |
336 | |
321 | |
337 | if (expect_false (nv == (U32)nv)) |
322 | if (ecb_expect_false (nv == (U32)nv)) |
338 | encode_uint (enc, 0x00, (U32)nv); |
323 | encode_uint (enc, 0x00, (U32)nv); |
339 | //TODO: maybe I32? |
324 | //TODO: maybe I32? |
340 | else if (expect_false (nv == (float)nv)) |
325 | else if (ecb_expect_false (nv == (float)nv)) |
341 | { |
326 | { |
342 | uint32_t fp = ecb_float_to_binary32 (nv); |
327 | uint32_t fp = ecb_float_to_binary32 (nv); |
343 | |
328 | |
344 | *enc->cur++ = 0xe0 | 26; |
329 | *enc->cur++ = 0xe0 | 26; |
345 | |
330 | |
… | |
… | |
433 | U32 maxdepth; // recursion depth limit |
418 | U32 maxdepth; // recursion depth limit |
434 | } dec_t; |
419 | } dec_t; |
435 | |
420 | |
436 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
421 | #define ERR(reason) SB if (!dec->err) dec->err = reason; goto fail; SE |
437 | |
422 | |
438 | #define WANT(len) if (expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data"); |
423 | #define WANT(len) if (ecb_expect_false (dec->cur + len > dec->end)) ERR ("unexpected end of CBOR data") |
439 | |
424 | |
440 | #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) |
425 | #define DEC_INC_DEPTH if (++dec->depth > dec->cbor.max_depth) ERR (ERR_NESTING_EXCEEDED) |
441 | #define DEC_DEC_DEPTH --dec->depth |
426 | #define DEC_DEC_DEPTH --dec->depth |
442 | |
427 | |
443 | static UV |
428 | static UV |
… | |
… | |
504 | |
489 | |
505 | for (;;) |
490 | for (;;) |
506 | { |
491 | { |
507 | WANT (1); |
492 | WANT (1); |
508 | |
493 | |
509 | if (*dec->cur == 0xe0 | 31) |
494 | if (*dec->cur == (0xe0 | 31)) |
510 | { |
495 | { |
511 | ++dec->cur; |
496 | ++dec->cur; |
512 | break; |
497 | break; |
513 | } |
498 | } |
514 | |
499 | |
… | |
… | |
547 | |
532 | |
548 | for (;;) |
533 | for (;;) |
549 | { |
534 | { |
550 | WANT (1); |
535 | WANT (1); |
551 | |
536 | |
552 | if (*dec->cur == 0xe0 | 31) |
537 | if (*dec->cur == (0xe0 | 31)) |
553 | { |
538 | { |
554 | ++dec->cur; |
539 | ++dec->cur; |
555 | break; |
540 | break; |
556 | } |
541 | } |
557 | |
542 | |
… | |
… | |
752 | // not very fast, and certainly not robust against illegal input |
737 | // not very fast, and certainly not robust against illegal input |
753 | for (;;) |
738 | for (;;) |
754 | { |
739 | { |
755 | WANT (1); |
740 | WANT (1); |
756 | |
741 | |
757 | if (*dec->cur == 0xe0 | 31) |
742 | if (*dec->cur == (0xe0 | 31)) |
758 | { |
743 | { |
759 | ++dec->cur; |
744 | ++dec->cur; |
760 | break; |
745 | break; |
761 | } |
746 | } |
762 | |
747 | |
… | |
… | |
778 | |
763 | |
779 | return sv; |
764 | return sv; |
780 | |
765 | |
781 | fail: |
766 | fail: |
782 | return &PL_sv_undef; |
767 | return &PL_sv_undef; |
|
|
768 | } |
|
|
769 | |
|
|
770 | static SV * |
|
|
771 | decode_tagged (dec_t *dec) |
|
|
772 | { |
|
|
773 | UV tag = decode_uint (dec); |
|
|
774 | SV *sv = decode_sv (dec); |
|
|
775 | |
|
|
776 | if (tag == 55799) // 2.4.5 Self-Describe CBOR |
|
|
777 | return sv; |
|
|
778 | |
|
|
779 | AV *av = newAV (); |
|
|
780 | av_push (av, newSVuv (tag)); |
|
|
781 | av_push (av, sv); |
|
|
782 | return newRV_noinc ((SV *)av); |
783 | } |
783 | } |
784 | |
784 | |
785 | static SV * |
785 | static SV * |
786 | decode_sv (dec_t *dec) |
786 | decode_sv (dec_t *dec) |
787 | { |
787 | { |
… | |
… | |
801 | case 4: // array |
801 | case 4: // array |
802 | return decode_av (dec); |
802 | return decode_av (dec); |
803 | case 5: // map |
803 | case 5: // map |
804 | return decode_hv (dec); |
804 | return decode_hv (dec); |
805 | case 6: // tag |
805 | case 6: // tag |
806 | abort (); |
806 | return decode_tagged (dec); |
807 | break; |
|
|
808 | case 7: // misc |
807 | case 7: // misc |
809 | switch (*dec->cur++ & 31) |
808 | switch (*dec->cur++ & 31) |
810 | { |
809 | { |
811 | case 20: |
810 | case 20: |
812 | #if CBOR_SLOW |
811 | #if CBOR_SLOW |
… | |
… | |
820 | return newSVsv (cbor_true); |
819 | return newSVsv (cbor_true); |
821 | case 22: |
820 | case 22: |
822 | return newSVsv (&PL_sv_undef); |
821 | return newSVsv (&PL_sv_undef); |
823 | |
822 | |
824 | case 25: |
823 | case 25: |
825 | // half float |
|
|
826 | abort (); |
|
|
827 | break; |
824 | { |
|
|
825 | WANT (2); |
|
|
826 | |
|
|
827 | uint16_t fp = (dec->cur[0] << 8) | dec->cur[1]; |
|
|
828 | dec->cur += 2; |
|
|
829 | |
|
|
830 | return newSVnv (ecb_binary16_to_float (fp)); |
|
|
831 | } |
828 | |
832 | |
829 | case 26: |
833 | case 26: |
830 | { |
834 | { |
831 | uint32_t fp; |
835 | uint32_t fp; |
832 | WANT (4); |
836 | WANT (4); |
… | |
… | |
975 | |
979 | |
976 | if (offset_return) |
980 | if (offset_return) |
977 | *offset_return = dec.cur; |
981 | *offset_return = dec.cur; |
978 | |
982 | |
979 | if (!(offset_return || !sv)) |
983 | if (!(offset_return || !sv)) |
980 | { |
|
|
981 | if (*dec.cur && !dec.err) |
984 | if (dec.cur != dec.end && !dec.err) |
982 | { |
|
|
983 | dec.err = "garbage after CBOR object"; |
985 | dec.err = "garbage after CBOR object"; |
|
|
986 | |
|
|
987 | if (dec.err) |
|
|
988 | { |
984 | SvREFCNT_dec (sv); |
989 | SvREFCNT_dec (sv); |
985 | sv = 0; |
|
|
986 | } |
|
|
987 | } |
|
|
988 | |
|
|
989 | if (!sv) |
|
|
990 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); |
990 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); |
|
|
991 | } |
991 | |
992 | |
992 | sv = sv_2mortal (sv); |
993 | sv = sv_2mortal (sv); |
993 | |
994 | |
994 | return sv; |
995 | return sv; |
995 | } |
996 | } |