File Coverage

cbor_free_decode.c
Criterion Covered Total %
statement 408 436 93.5
branch 175 200 87.5
condition n/a
subroutine n/a
pod n/a
total 583 636 91.6


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #include "EXTERN.h"
4             #include "perl.h"
5             #include "XSUB.h"
6              
7             #include "cbor_free_common.h"
8             #include "cbor_free_decode.h"
9              
10             #include
11             #include
12              
13             // For ntohs and ntohl
14             #include
15              
16             #define _IS_INCOMPLETE(decstate, len) \
17             ((len + decstate->curbyte) > decstate->end)
18              
19             #define _SET_INCOMPLETE(decstate, len) \
20             decstate->incomplete_by = (len + decstate->curbyte) - decstate->end;
21              
22             #define _RETURN_IF_INCOMPLETE( decstate, len, toreturn ) \
23             if (_IS_INCOMPLETE(decstate, len)) { \
24             _SET_INCOMPLETE(decstate, len); \
25             return toreturn; \
26             }
27              
28             #define _RETURN_IF_SET_INCOMPLETE(decstate, toreturn) \
29             if (decstate->incomplete_by) return toreturn;
30              
31             #define SHOULD_VALIDATE_UTF8(decstate, major_type) \
32             major_type == CBOR_TYPE_UTF8 \
33             || decstate->string_decode_mode == CBF_STRING_DECODE_ALWAYS
34              
35             //----------------------------------------------------------------------
36              
37             // Basically ntohll(), but it accepts a pointer.
38 19           static inline UV _buffer_u64_to_uv( unsigned char *buffer ) {
39 19           UV num = 0;
40              
41             #if IS_64_BIT
42 19           num |= *(buffer++);
43 19           num <<= 8;
44              
45 19           num |= *(buffer++);
46 19           num <<= 8;
47              
48 19           num |= *(buffer++);
49 19           num <<= 8;
50              
51 19           num |= *(buffer++);
52 19           num <<= 8;
53             #else
54             buffer += 4;
55             #endif
56              
57 19           num |= *(buffer++);
58 19           num <<= 8;
59              
60 19           num |= *(buffer++);
61 19           num <<= 8;
62              
63 19           num |= *(buffer++);
64 19           num <<= 8;
65              
66 19           num |= *(buffer++);
67              
68 19           return num;
69             }
70              
71             const char *MAJOR_TYPE_DESCRIPTION[] = {
72             "unsigned integer",
73             "negative integer",
74             "byte string",
75             "text string",
76             "array",
77             "map",
78             "tag",
79             "miscellaneous",
80             };
81              
82             //----------------------------------------------------------------------
83             // Croakers
84              
85             static const char* UV_TO_STR_TMPL = (sizeof(UV) == 8 ? "%llu" : "%lu");
86             static const char* IV_TO_STR_TMPL = (sizeof(UV) == 8 ? "%lld" : "%ld");
87              
88 23           UV _uv_to_str(UV num, char *numstr, const char strlen) {
89 23 50         return my_snprintf( numstr, strlen, UV_TO_STR_TMPL, num );
    50          
90             }
91              
92 2           UV _iv_to_str(IV num, char *numstr, const char strlen) {
93 2 50         return my_snprintf( numstr, strlen, IV_TO_STR_TMPL, num );
    50          
94             }
95              
96 206           void _free_decode_state_if_not_persistent( pTHX_ decode_ctx* decstate ) {
97 206 100         if (!(decstate->flags & CBF_FLAG_PERSIST_STATE)) {
98 195           free_decode_state(aTHX_ decstate);
99             }
100 206           }
101              
102 146           static inline void _croak_incomplete( pTHX_ decode_ctx* decstate ) {
103              
104 292           SV* args[2] = {
105 146           newSVpvs("Incomplete"),
106 146           newSVuv(decstate->incomplete_by),
107             };
108              
109 146           _free_decode_state_if_not_persistent(aTHX_ decstate);
110              
111 146           cbf_die_with_arguments( aTHX_ 2, args );
112 0           }
113              
114 49           static inline void _croak_invalid_control( pTHX_ decode_ctx* decstate ) {
115 49           const uint8_t ord = (uint8_t) *(decstate->curbyte);
116 49           UV offset = decstate->curbyte - decstate->start;
117              
118 49           _free_decode_state_if_not_persistent(aTHX_ decstate);
119              
120 147           SV* args[3] = {
121 49           newSVpvs("InvalidControl"),
122 49           newSVuv(ord),
123 49           newSVuv(offset),
124             };
125              
126 49           cbf_die_with_arguments( aTHX_ 3, args );
127              
128             assert(0);
129 0           }
130              
131 2           void _croak_invalid_utf8( pTHX_ decode_ctx* decstate, char *string, STRLEN len ) {
132 2           _free_decode_state_if_not_persistent(aTHX_ decstate);
133              
134 4           SV* args[2] = {
135 2           newSVpvs("InvalidUTF8"),
136 2           newSVpvn(string, len),
137             };
138              
139 2           cbf_die_with_arguments( aTHX_ 2, args );
140              
141             assert(0);
142 0           }
143              
144 8           void _croak_invalid_map_key( pTHX_ decode_ctx* decstate ) {
145 8           const uint8_t byte = decstate->curbyte[0];
146 8           UV offset = decstate->curbyte - decstate->start;
147              
148 8           _free_decode_state_if_not_persistent(aTHX_ decstate);
149              
150             char bytebuf[5];
151              
152             char *bytestr;
153              
154 8           switch (byte) {
155             case CBOR_FALSE:
156 2           bytestr = "false";
157 2           break;
158             case CBOR_TRUE:
159 1           bytestr = "true";
160 1           break;
161             case CBOR_NULL:
162 1           bytestr = "null";
163 1           break;
164             case CBOR_UNDEFINED:
165 1           bytestr = "undefined";
166 1           break;
167             case CBOR_HALF_FLOAT:
168 0           bytestr = "half-float";
169             case CBOR_FLOAT:
170 0           bytestr = "float";
171             case CBOR_DOUBLE:
172 1           bytestr = "double float";
173 1           break;
174             default:
175 2           switch ((byte & 0xe0) >> 5) {
176             case CBOR_TYPE_ARRAY:
177 1           bytestr = "array";
178 1           break;
179             case CBOR_TYPE_MAP:
180 1           bytestr = "map";
181 1           break;
182             default:
183 0 0         my_snprintf( bytebuf, 5, "0x%02x", byte );
184 0           bytestr = bytebuf;
185             }
186             }
187              
188 24           SV* args[3] = {
189 8           newSVpvs("InvalidMapKey"),
190 8           newSVpv(bytestr, 0),
191 8           newSVuv(offset),
192             };
193              
194 8           cbf_die_with_arguments( aTHX_ 3, args );
195              
196             assert(0);
197 0           }
198              
199 0           void _croak_cannot_decode_64bit( pTHX_ decode_ctx* decstate ) {
200 0           UV offset = decstate->curbyte - decstate->start;
201              
202 0           _free_decode_state_if_not_persistent(aTHX_ decstate);
203              
204 0           SV* args[3] = {
205 0           newSVpvs("CannotDecode64Bit"),
206 0           newSVpvn( decstate->curbyte, 8),
207 0           newSVuv(offset),
208             };
209              
210 0           cbf_die_with_arguments( aTHX_ 3, args );
211              
212             assert(0);
213 0           }
214              
215 1           void _croak_cannot_decode_negative( pTHX_ decode_ctx* decstate, UV abs, STRLEN offset ) {
216 1           _free_decode_state_if_not_persistent(aTHX_ decstate);
217              
218 3           SV* args[3] = {
219 1           newSVpvs("NegativeIntTooLow"),
220 1           newSVuv(abs),
221 1           newSVuv(offset),
222             };
223              
224 1           cbf_die_with_arguments( aTHX_ 3, args );
225              
226             assert(0);
227 0           }
228              
229 33           void _warn_unhandled_tag( pTHX_ UV tagnum, U8 value_major_type ) {
230             char tmpl[255];
231 33 50         my_snprintf( tmpl, sizeof(tmpl), "Ignoring unrecognized CBOR tag #%s (major type %%u, %%s)!", UV_TO_STR_TMPL );
232              
233 33           warn(tmpl, tagnum, value_major_type, MAJOR_TYPE_DESCRIPTION[value_major_type]);
234 33           }
235              
236             //----------------------------------------------------------------------
237              
238 96           static inline void _validate_utf8_string_if_needed( pTHX_ decode_ctx* decstate, char *buffer, STRLEN len ) {
239              
240 96 100         if (!(decstate->flags & CBF_FLAG_NAIVE_UTF8) && !is_utf8_string( (U8 *)buffer, len)) {
    100          
241 2           _croak_invalid_utf8( aTHX_ decstate, buffer, len );
242             }
243 94           }
244              
245             //----------------------------------------------------------------------
246             // DECODER:
247             //----------------------------------------------------------------------
248              
249             // Sets incomplete_by.
250 6068           static inline UV _parse_for_uint_len2( pTHX_ decode_ctx* decstate ) {
251 6068           union control_byte *control = (union control_byte *) decstate->curbyte;
252              
253             UV ret;
254              
255 6068           switch (control->pieces.length_type) {
256             case CBOR_LENGTH_SMALL:
257              
258 264 100         _RETURN_IF_INCOMPLETE( decstate, 2, 0 );
259              
260 258           ++decstate->curbyte;
261              
262 258           ret = (uint8_t) decstate->curbyte[0];
263              
264 258           ++decstate->curbyte;
265              
266 258           break;
267              
268             case CBOR_LENGTH_MEDIUM:
269 56 100         _RETURN_IF_INCOMPLETE( decstate, 3, 0);
270              
271 46           ++decstate->curbyte;
272              
273 46           ret = ntohs( *((uint16_t *) decstate->curbyte) );
274              
275 46           decstate->curbyte += 2;
276              
277 46           break;
278              
279             case CBOR_LENGTH_LARGE:
280 162 100         _RETURN_IF_INCOMPLETE( decstate, 5, 0);
281              
282 128           ++decstate->curbyte;
283              
284 128           ret = ntohl( *((uint32_t *) decstate->curbyte) );
285              
286 128           decstate->curbyte += 4;
287              
288 128           break;
289              
290             case CBOR_LENGTH_HUGE:
291 59 100         _RETURN_IF_INCOMPLETE( decstate, 9, 0);
292              
293 19           ++decstate->curbyte;
294              
295             #if !IS_64_BIT
296              
297             if (decstate->curbyte[0] || decstate->curbyte[1] || decstate->curbyte[2] || decstate->curbyte[3]) {
298             _croak_cannot_decode_64bit( aTHX_ decstate );
299             }
300             #endif
301 19           ret = _buffer_u64_to_uv( (uint8_t *) decstate->curbyte );
302              
303 19           decstate->curbyte += 8;
304              
305 19           break;
306              
307             case 0x1c:
308             case 0x1d:
309             case 0x1e:
310             case 0x1f: // indefinite must be handled outside this function.
311 21           _croak_invalid_control( aTHX_ decstate );
312 0           return 0; // Silence compiler warning.
313              
314             default:
315 5506           ret = (uint8_t) control->pieces.length_type;
316              
317 5506           decstate->curbyte++;
318             }
319              
320 5957           return ret;
321             }
322              
323             //----------------------------------------------------------------------
324              
325             // Sets incomplete_by.
326 171           SV *_decode_array( pTHX_ decode_ctx* decstate ) {
327 171           union control_byte *control = (union control_byte *) decstate->curbyte;
328              
329 171           AV *array = newAV();
330 171           sv_2mortal( (SV *) array );
331              
332 171           SV *cur = NULL;
333              
334 171 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
335 39           ++decstate->curbyte;
336              
337             while (1) {
338 83 100         _RETURN_IF_INCOMPLETE( decstate, 1, NULL );
339              
340 79 100         if ( decstate->curbyte[0] == '\xff') {
341 12           ++decstate->curbyte;
342 12           break;
343             }
344              
345 67           cur = cbf_decode_one( aTHX_ decstate );
346              
347 67 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
348              
349 44           av_push(array, cur);
350 56           }
351             }
352             else {
353 132           SSize_t array_length = _parse_for_uint_len2( aTHX_ decstate );
354 129 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
355              
356 127 100         if (array_length) {
357 108           av_fill(array, array_length - 1);
358              
359             SSize_t i;
360 587 100         for (i=0; i
361 533           cur = cbf_decode_one( aTHX_ decstate );
362 484 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
363              
364 479 50         if (!av_store(array, i, cur)) {
365 0           _croak("Failed to store item in array!");
366             }
367             }
368             }
369             }
370              
371 85           return newRV_inc( (SV *) array );
372             }
373              
374             // Sets incomplete_by.
375 1909           UV _decode_uint( pTHX_ decode_ctx* decstate ) {
376 1909           union control_byte *control = (union control_byte *) decstate->curbyte;
377              
378 1909 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
379 1           _croak_invalid_control( aTHX_ decstate );
380             }
381              
382 1908           return _parse_for_uint_len2( aTHX_ decstate );
383             }
384              
385             // Sets incomplete_by.
386 46           IV _decode_negint( pTHX_ decode_ctx* decstate ) {
387 46           union control_byte *control = (union control_byte *) decstate->curbyte;
388              
389 46 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
390 1           _croak_invalid_control( aTHX_ decstate );
391             }
392              
393 45           UV positive = _parse_for_uint_len2( aTHX_ decstate );
394 42 100         _RETURN_IF_SET_INCOMPLETE(decstate, 0);
395              
396             #if IS_64_BIT
397 26 100         if (positive >= 0x8000000000000000U) {
398 1           _croak_cannot_decode_negative( aTHX_ decstate, positive, decstate->curbyte - decstate->start - 8 );
399             }
400             #else
401             if (positive >= 0x80000000U) {
402             STRLEN offset = decstate->curbyte - decstate->start;
403              
404             if (control->pieces.length_type == 0x1a) {
405             offset -= 4;
406             }
407             else {
408             offset -= 8;
409             }
410              
411             _croak_cannot_decode_negative( aTHX_ decstate, positive, offset );
412             }
413             #endif
414              
415 25           return( -1 - (int64_t) positive );
416             }
417              
418             // Sets incomplete_by.
419             // Return indicates whether string_h has SV.
420 3726           bool _decode_str( pTHX_ decode_ctx* decstate, union numbuf_or_sv* string_u ) {
421 3726           union control_byte *control = (union control_byte *) decstate->curbyte;
422              
423 3726 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
424 11           ++decstate->curbyte;
425              
426 11           SV *string = newSVpvs_flags("", SVs_TEMP);
427 11           string_u->sv = string;
428              
429             while (1) {
430 23 100         _RETURN_IF_INCOMPLETE( decstate, 1, false );
431              
432 21 100         if (decstate->curbyte[0] == '\xff') {
433 7           ++decstate->curbyte;
434 7           break;
435             }
436              
437             //TODO: Require the same major type.
438              
439 14           SV *cur = cbf_decode_one( aTHX_ decstate );
440              
441 14 100         _RETURN_IF_SET_INCOMPLETE( decstate, false );
442              
443 12           sv_2mortal(cur);
444              
445 12           sv_catsv(string, cur);
446 12           }
447              
448 7           SvREFCNT_inc(string);
449              
450 7           return true;
451             }
452              
453 3715           string_u->numbuf.num.uv = _parse_for_uint_len2( aTHX_ decstate );
454 3709 100         _RETURN_IF_SET_INCOMPLETE(decstate, false);
455              
456 3668 100         _RETURN_IF_INCOMPLETE( decstate, string_u->numbuf.num.uv, false );
457              
458 3637           string_u->numbuf.buffer = decstate->curbyte;
459              
460 3637           decstate->curbyte += string_u->numbuf.num.uv;
461              
462 3637           return false;
463             }
464              
465             // Sets incomplete_by.
466 2561           void _decode_hash_entry( pTHX_ decode_ctx* decstate, HV *hash ) {
467 2566 100         _RETURN_IF_INCOMPLETE( decstate, 1, );
468              
469 2559           union control_byte *control = (union control_byte *) decstate->curbyte;
470              
471             union numbuf_or_sv my_key;
472 2559           my_key.numbuf.buffer = NULL;
473              
474             // This is going to be a hash key, so it can’t usefully be
475             // anything but a string/PV.
476             I32 keylen;
477             char *keystr;
478              
479 2559           bool my_key_has_sv = false;
480              
481 2559           switch (control->pieces.major_type) {
482             case CBOR_TYPE_UINT:
483 23           my_key.numbuf.num.uv = _decode_uint( aTHX_ decstate );
484 23 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
485              
486 22           keystr = (char *) decstate->scratch.bytes;
487 22           keylen = _uv_to_str( my_key.numbuf.num.uv, keystr, sizeof(decstate->scratch.bytes));
488             // fprintf(stderr, "key (%p) is uint: %.*s\n", keystr, keylen, keystr);
489              
490 22           break;
491              
492             case CBOR_TYPE_NEGINT:
493 3           my_key.numbuf.num.iv = _decode_negint( aTHX_ decstate );
494 3 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
495              
496 2           keystr = (char *) decstate->scratch.bytes;
497 2           keylen = _iv_to_str( my_key.numbuf.num.iv, keystr, sizeof(decstate->scratch.bytes));
498              
499 2           break;
500              
501             case CBOR_TYPE_BINARY:
502             case CBOR_TYPE_UTF8:
503 2525           my_key_has_sv = _decode_str( aTHX_ decstate, &my_key );
504 2525 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
505              
506 2522 100         if (!my_key_has_sv) {
507 2519 50         if (my_key.numbuf.num.uv > 0x7fffffffU) {
508 0           _croak("key too long!");
509             }
510              
511 2519           keystr = my_key.numbuf.buffer;
512              
513 2519 100         if (SHOULD_VALIDATE_UTF8(decstate, control->pieces.major_type)) {
    50          
514 30           _validate_utf8_string_if_needed( aTHX_ decstate, keystr, my_key.numbuf.num.uv );
515              
516 29 50         keylen = decstate->string_decode_mode == CBF_STRING_DECODE_NEVER ? my_key.numbuf.num.uv : -my_key.numbuf.num.uv;
517             }
518             else {
519 2489           keylen = my_key.numbuf.num.uv;
520             }
521             }
522              
523 2521           break;
524              
525             default:
526 8           _croak_invalid_map_key( aTHX_ decstate);
527 0           return; // Silence compiler warning.
528             }
529              
530 2545           SV *curval = cbf_decode_one( aTHX_ decstate );
531              
532 2545 100         if (decstate->incomplete_by) {
533 3 100         if (my_key_has_sv) {
534 3           SvREFCNT_dec( my_key.sv );
535             }
536             }
537 2542 100         else if (my_key_has_sv) {
538 2           hv_store_ent(hash, my_key.sv, curval, 0);
539             }
540             else {
541 2545           hv_store(hash, keystr, keylen, curval, 0);
542             }
543             }
544              
545             // Sets incomplete_by.
546 67           SV *_decode_map( pTHX_ decode_ctx* decstate ) {
547 67           union control_byte *control = (union control_byte *) decstate->curbyte;
548              
549 67           HV *hash = newHV();
550 67           sv_2mortal( (SV *) hash );
551              
552 67 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
553 8           ++decstate->curbyte;
554              
555             while (1) {
556 13 100         _RETURN_IF_INCOMPLETE( decstate, 1, NULL );
557              
558 11 100         if (decstate->curbyte[0] == '\xff') {
559 4           ++decstate->curbyte;
560 4           break;
561             }
562              
563 7           _decode_hash_entry( aTHX_ decstate, hash );
564              
565             // TODO: Recursively decref all hash members.
566 7 100         if ( decstate->incomplete_by ) {
567 2           return NULL;
568             }
569 9           }
570             }
571             else {
572 59           SSize_t keycount = _parse_for_uint_len2( aTHX_ decstate );
573 56 100         if ( decstate->incomplete_by ) {
574 5           return NULL;
575             }
576              
577 51 100         if (keycount) {
578 2576 100         while (keycount > 0) {
579 2554           _decode_hash_entry( aTHX_ decstate, hash );
580              
581             // TODO: Recursively decref all hash members.
582 2545 100         if ( decstate->incomplete_by ) {
583 8           return NULL;
584             }
585              
586 2537           --keycount;
587             }
588             }
589             }
590              
591 38           return newRV_inc( (SV *) hash);
592             }
593              
594             //----------------------------------------------------------------------
595              
596             // Taken from RFC 7049:
597 7           double decode_half_float(uint8_t *halfp) {
598 7           int half = (halfp[0] << 8) + halfp[1];
599 7           int exp = (half >> 10) & 0x1f;
600 7           int mant = half & 0x3ff;
601             double val;
602 7 50         if (exp == 0) val = ldexp(mant, -24);
603 7 100         else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
604 6 100         else val = mant == 0 ? INFINITY : NAN;
605 7 100         return half & 0x8000 ? -val : val;
606             }
607              
608 24           static inline float _decode_float_to_host( pTHX_ decode_ctx* decstate, uint8_t *ptr ) {
609 24           *((uint32_t *) decstate->scratch.bytes) = ntohl( *((uint32_t *) ptr) );
610              
611 24           return decstate->scratch.as_float;
612             }
613              
614 63           static inline double _decode_double_to_le( decode_ctx* decstate, uint8_t *ptr ) {
615 63           decstate->scratch.bytes[0] = ptr[7];
616 63           decstate->scratch.bytes[1] = ptr[6];
617 63           decstate->scratch.bytes[2] = ptr[5];
618 63           decstate->scratch.bytes[3] = ptr[4];
619 63           decstate->scratch.bytes[4] = ptr[3];
620 63           decstate->scratch.bytes[5] = ptr[2];
621 63           decstate->scratch.bytes[6] = ptr[1];
622 63           decstate->scratch.bytes[7] = ptr[0];
623              
624 63           return decstate->scratch.as_double;
625             }
626              
627             //----------------------------------------------------------------------
628              
629             // Sets incomplete_by.
630 1201           static inline SV *_decode_str_to_sv( pTHX_ decode_ctx* decstate ) {
631             union numbuf_or_sv string;
632              
633 1201 100         if (_decode_str( aTHX_ decstate, &string )) {
634 4           return string.sv;
635             }
636              
637 1191 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
638              
639 1195           return newSVpvn( string.numbuf.buffer, string.numbuf.num.uv );
640             }
641              
642             // Sets incomplete_by.
643 3949           SV *cbf_decode_one( pTHX_ decode_ctx* decstate ) {
644 3949           SV *ret = NULL;
645              
646 3949 100         _RETURN_IF_INCOMPLETE( decstate, 1, NULL );
647              
648 3938           union control_byte *control = (union control_byte *) decstate->curbyte;
649              
650             // fprintf(stderr, "major type: %d\n", control->pieces.major_type);
651              
652 3938           switch (control->pieces.major_type) {
653             case CBOR_TYPE_UINT:
654 1886           ret = newSVuv( _decode_uint( aTHX_ decstate ) );
655 1882 100         if ( decstate->incomplete_by ) {
656 15           SvREFCNT_dec(ret);
657 188           return NULL;
658             }
659              
660 1867           break;
661             case CBOR_TYPE_NEGINT:
662 43           ret = newSViv( _decode_negint( aTHX_ decstate ) );
663 38 100         if ( decstate->incomplete_by ) {
664 15           SvREFCNT_dec(ret);
665 15           return NULL;
666             }
667              
668 23           break;
669             case CBOR_TYPE_BINARY:
670             case CBOR_TYPE_UTF8:
671 1201           ret = _decode_str_to_sv( aTHX_ decstate );
672 1195 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
673              
674 1122 100         if (SHOULD_VALIDATE_UTF8(decstate, control->pieces.major_type)) {
    100          
675 66 50         _validate_utf8_string_if_needed( aTHX_ decstate, SvPV_nolen(ret), SvCUR(ret));
676              
677             // Always set the UTF8 flag, even if it’s not needed.
678             // This helps ensure that text strings will round-trip
679             // through Perl.
680 65 100         if (decstate->string_decode_mode != CBF_STRING_DECODE_NEVER) SvUTF8_on(ret);
681             }
682              
683 1121           break;
684             case CBOR_TYPE_ARRAY:
685 171           ret = _decode_array( aTHX_ decstate );
686 119 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
687              
688 85           break;
689             case CBOR_TYPE_MAP:
690 67           ret = _decode_map( aTHX_ decstate );
691 55 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
692              
693 38           break;
694             case CBOR_TYPE_TAG:
695              
696 198 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
697 1           _croak_invalid_control( aTHX_ decstate );
698             }
699              
700 197           UV tagnum = _parse_for_uint_len2( aTHX_ decstate );
701 194 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
702              
703 179           U8 value_major_type = ((union control_byte *) decstate->curbyte)->pieces.major_type;
704              
705 191 100         if (tagnum == CBOR_TAG_SHAREDREF && decstate->reflist) {
    100          
706 12 50         if (value_major_type != CBOR_TYPE_UINT) {
707             char tmpl[255];
708 0 0         my_snprintf( tmpl, sizeof(tmpl), "Shared ref type must be uint, not %%u (%%s)!" );
709 0           croak(tmpl, value_major_type, MAJOR_TYPE_DESCRIPTION[value_major_type]);
710             }
711              
712 12           UV refnum = _parse_for_uint_len2( aTHX_ decstate );
713 12 50         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
714              
715 12 50         if (refnum >= decstate->reflistlen) {
716 0           _croak("Missing shareable!");
717             }
718              
719 12           ret = decstate->reflist[refnum];
720 12           SvREFCNT_inc(ret);
721             }
722             else {
723 167           ret = cbf_decode_one( aTHX_ decstate );
724 167 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
725              
726 162 100         if (tagnum == CBOR_TAG_INDIRECTION) {
727 17           ret = newRV_noinc(ret);
728             }
729 145 100         else if (tagnum == CBOR_TAG_SHAREABLE && decstate->reflist) {
    100          
730 12           ++decstate->reflistlen;
731 12 50         Renew( decstate->reflist, decstate->reflistlen, void * );
732              
733 12           decstate->reflist[ decstate->reflistlen - 1 ] = (SV *) ret;
734             }
735              
736 133 100         else if (decstate->tag_handler) {
737 102           HV *my_tag_handler = decstate->tag_handler;
738              
739 102           SV **handler_cr = hv_fetch( my_tag_handler, (char *) &tagnum, sizeof(UV), 0 );
740              
741 102 100         if (handler_cr && *handler_cr && SvOK(*handler_cr)) {
    50          
    100          
    50          
    50          
742 100           ret = cbf_call_scalar_with_arguments( aTHX_ *handler_cr, 1, &ret );
743             }
744             else {
745 102           _warn_unhandled_tag( aTHX_ tagnum, value_major_type );
746             }
747             }
748             else {
749 31           _warn_unhandled_tag( aTHX_ tagnum, value_major_type );
750             }
751             }
752              
753 174           break;
754             case CBOR_TYPE_OTHER:
755 372           switch (control->u8) {
756             case CBOR_FALSE:
757 3           ret = newSVsv( cbf_get_false() );
758 3           ++decstate->curbyte;
759 3           break;
760              
761             case CBOR_TRUE:
762 6           ret = newSVsv( cbf_get_true() );
763 6           ++decstate->curbyte;
764 6           break;
765              
766             case CBOR_NULL:
767             case CBOR_UNDEFINED:
768 230           ret = &PL_sv_undef;
769 230           ++decstate->curbyte;
770 230           break;
771              
772             case CBOR_HALF_FLOAT:
773 9 100         _RETURN_IF_INCOMPLETE( decstate, 3, NULL );
774              
775 7           ret = newSVnv( decode_half_float( (uint8_t *) (1 + decstate->curbyte) ) );
776              
777 7           decstate->curbyte += 3;
778 7           break;
779              
780             case CBOR_FLOAT:
781 28 100         _RETURN_IF_INCOMPLETE( decstate, 5, NULL );
782              
783             float decoded_flt;
784              
785             #if IS_LITTLE_ENDIAN
786 24           decoded_flt = _decode_float_to_host( aTHX_ decstate, (uint8_t *) (1 + decstate->curbyte ) );
787             #else
788             decoded_flt = *( (float *) (1 + decstate->curbyte) );
789             #endif
790              
791 24           ret = newSVnv( (NV) decoded_flt );
792              
793 24           decstate->curbyte += 5;
794 24           break;
795              
796             case CBOR_DOUBLE:
797 71 100         _RETURN_IF_INCOMPLETE( decstate, 9, NULL );
798              
799             double decoded_dbl;
800              
801             #if IS_LITTLE_ENDIAN
802 63           decoded_dbl = _decode_double_to_le( decstate, (uint8_t *) (1 + decstate->curbyte ) );
803             #else
804             decoded_dbl = *( (double *) (1 + decstate->curbyte) );
805             #endif
806              
807 63           ret = newSVnv( (NV) decoded_dbl );
808              
809 63           decstate->curbyte += 9;
810 63           break;
811              
812             default:
813 25           _croak_invalid_control( aTHX_ decstate );
814             }
815              
816 333           break;
817              
818             default:
819 0           _croak("Unknown type!");
820             }
821              
822 3840           return ret;
823             }
824              
825             /*
826             * Possible states:
827             *
828             * 1) We’re initializing.
829             * 2) We just concat’ed two SVPVs (same as initializing).
830             * 3) We just shortened from the beginning.
831             */
832              
833 629           void renew_decode_state_buffer( pTHX_ decode_ctx *decode_state, SV *cbor ) {
834 629           STRLEN cborlen = SvCUR(cbor);
835              
836 629           char *cborstr = SvPVX(cbor);
837              
838             STRLEN offset;
839 629 100         if (decode_state->curbyte == NULL) {
840 599           offset = 0;
841             }
842             else {
843 30           offset = decode_state->curbyte - decode_state->start;
844             }
845              
846 629           decode_state->start = cborstr;
847 629           decode_state->size = cborlen;
848 629           decode_state->curbyte = cborstr + offset;
849 629           decode_state->end = cborstr + cborlen;
850 629           }
851              
852 18           void advance_decode_state_buffer( pTHX_ decode_ctx *decode_state ) {
853 18           STRLEN diff = decode_state->curbyte - decode_state->start;
854              
855 18           decode_state->start = decode_state->curbyte;
856 18           decode_state->size -= diff;
857 18           }
858              
859 579           decode_ctx* create_decode_state( pTHX_ SV *cbor, HV *tag_handler, UV flags ) {
860             decode_ctx *decode_state;
861 579           Newx( decode_state, 1, decode_ctx );
862              
863 579           decode_state->curbyte = NULL;
864              
865 579 100         if (cbor) {
866 472           renew_decode_state_buffer( aTHX_ decode_state, cbor );
867             }
868              
869 579           decode_state->tag_handler = tag_handler;
870 579 50         if (NULL != tag_handler) {
871 0           SvREFCNT_inc((SV *) tag_handler);
872             }
873              
874 579           decode_state->reflist = NULL;
875 579           decode_state->reflistlen = 0;
876 579           decode_state->flags = flags;
877 579           decode_state->incomplete_by = 0;
878              
879 579           decode_state->string_decode_mode = CBF_STRING_DECODE_CBOR;
880              
881 579 50         if (flags & CBF_FLAG_PRESERVE_REFERENCES) {
882 0           ensure_reflist_exists( aTHX_ decode_state );
883             }
884              
885 579           return decode_state;
886             }
887              
888 4           void ensure_reflist_exists( pTHX_ decode_ctx* decode_state) {
889 4 50         if (NULL == decode_state->reflist) {
890 4           Newx( decode_state->reflist, 0, void * );
891             }
892 4           }
893              
894 583           void delete_reflist( pTHX_ decode_ctx* decode_state) {
895 583 100         if (NULL != decode_state->reflist) {
896 4           Safefree(decode_state->reflist);
897 4           decode_state->reflist = NULL;
898 4           decode_state->reflistlen = 0;
899             }
900 583           }
901              
902 4           void reset_reflist_if_needed( pTHX_ decode_ctx* decode_state) {
903 4 100         if (decode_state->reflistlen) {
904 2           delete_reflist( aTHX_ decode_state );
905 2           ensure_reflist_exists( aTHX_ decode_state );
906             }
907 4           }
908              
909 579           void free_decode_state( pTHX_ decode_ctx* decode_state) {
910 579           delete_reflist( aTHX_ decode_state );
911              
912 579 100         if (NULL != decode_state->tag_handler) {
913 102           SvREFCNT_dec((SV *) decode_state->tag_handler);
914 102           decode_state->tag_handler = NULL;
915             }
916              
917 579           Safefree(decode_state);
918 579           }
919              
920 590           SV *cbf_decode_document( pTHX_ decode_ctx *decode_state ) {
921 590           SV *RETVAL = cbf_decode_one( aTHX_ decode_state );
922              
923 530 100         if (decode_state->incomplete_by) {
924 146           _croak_incomplete( aTHX_ decode_state );
925             }
926              
927 384 100         if (decode_state->curbyte != decode_state->end) {
928 1           STRLEN bytes_count = decode_state->end - decode_state->curbyte;
929              
930             char numstr[24];
931 1           _uv_to_str(bytes_count, numstr, 24);
932              
933 1           char * words[2] = { numstr, NULL };
934              
935 1           call_argv("CBOR::Free::_warn_decode_leftover", G_DISCARD, words);
936             }
937              
938 384           return RETVAL;
939             }
940              
941 463           SV *cbf_decode( pTHX_ SV *cbor, HV *tag_handler, UV flags ) {
942              
943 463           decode_ctx *decode_state = create_decode_state( aTHX_ cbor, tag_handler, flags);
944              
945 463           SV *RETVAL = cbf_decode_document( aTHX_ decode_state );
946              
947 268           free_decode_state( aTHX_ decode_state);
948              
949 268           return RETVAL;
950             }