File Coverage

cbor_free_decode.c
Criterion Covered Total %
statement 409 437 93.5
branch 175 200 87.5
condition n/a
subroutine n/a
pod n/a
total 584 637 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(""); /* 5.10.0 lacks newSVpvs_flags() */
427 11           sv_2mortal(string);
428 11           string_u->sv = string;
429              
430             while (1) {
431 23 100         _RETURN_IF_INCOMPLETE( decstate, 1, false );
432              
433 21 100         if (decstate->curbyte[0] == '\xff') {
434 7           ++decstate->curbyte;
435 7           break;
436             }
437              
438             //TODO: Require the same major type.
439              
440 14           SV *cur = cbf_decode_one( aTHX_ decstate );
441              
442 14 100         _RETURN_IF_SET_INCOMPLETE( decstate, false );
443              
444 12           sv_2mortal(cur);
445              
446 12           sv_catsv(string, cur);
447 12           }
448              
449 7           SvREFCNT_inc(string);
450              
451 7           return true;
452             }
453              
454 3715           string_u->numbuf.num.uv = _parse_for_uint_len2( aTHX_ decstate );
455 3709 100         _RETURN_IF_SET_INCOMPLETE(decstate, false);
456              
457 3668 100         _RETURN_IF_INCOMPLETE( decstate, string_u->numbuf.num.uv, false );
458              
459 3637           string_u->numbuf.buffer = decstate->curbyte;
460              
461 3637           decstate->curbyte += string_u->numbuf.num.uv;
462              
463 3637           return false;
464             }
465              
466             // Sets incomplete_by.
467 2561           void _decode_hash_entry( pTHX_ decode_ctx* decstate, HV *hash ) {
468 2566 100         _RETURN_IF_INCOMPLETE( decstate, 1, );
469              
470 2559           union control_byte *control = (union control_byte *) decstate->curbyte;
471              
472             union numbuf_or_sv my_key;
473 2559           my_key.numbuf.buffer = NULL;
474              
475             // This is going to be a hash key, so it can’t usefully be
476             // anything but a string/PV.
477             I32 keylen;
478             char *keystr;
479              
480 2559           bool my_key_has_sv = false;
481              
482 2559           switch (control->pieces.major_type) {
483             case CBOR_TYPE_UINT:
484 23           my_key.numbuf.num.uv = _decode_uint( aTHX_ decstate );
485 23 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
486              
487 22           keystr = (char *) decstate->scratch.bytes;
488 22           keylen = _uv_to_str( my_key.numbuf.num.uv, keystr, sizeof(decstate->scratch.bytes));
489             // fprintf(stderr, "key (%p) is uint: %.*s\n", keystr, keylen, keystr);
490              
491 22           break;
492              
493             case CBOR_TYPE_NEGINT:
494 3           my_key.numbuf.num.iv = _decode_negint( aTHX_ decstate );
495 3 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
496              
497 2           keystr = (char *) decstate->scratch.bytes;
498 2           keylen = _iv_to_str( my_key.numbuf.num.iv, keystr, sizeof(decstate->scratch.bytes));
499              
500 2           break;
501              
502             case CBOR_TYPE_BINARY:
503             case CBOR_TYPE_UTF8:
504 2525           my_key_has_sv = _decode_str( aTHX_ decstate, &my_key );
505 2525 100         _RETURN_IF_SET_INCOMPLETE(decstate, );
506              
507 2522 100         if (!my_key_has_sv) {
508 2519 50         if (my_key.numbuf.num.uv > 0x7fffffffU) {
509 0           _croak("key too long!");
510             }
511              
512 2519           keystr = my_key.numbuf.buffer;
513              
514 2519 100         if (SHOULD_VALIDATE_UTF8(decstate, control->pieces.major_type)) {
    50          
515 30           _validate_utf8_string_if_needed( aTHX_ decstate, keystr, my_key.numbuf.num.uv );
516              
517 29 50         keylen = decstate->string_decode_mode == CBF_STRING_DECODE_NEVER ? my_key.numbuf.num.uv : -my_key.numbuf.num.uv;
518             }
519             else {
520 2489           keylen = my_key.numbuf.num.uv;
521             }
522             }
523              
524 2521           break;
525              
526             default:
527 8           _croak_invalid_map_key( aTHX_ decstate);
528 0           return; // Silence compiler warning.
529             }
530              
531 2545           SV *curval = cbf_decode_one( aTHX_ decstate );
532              
533 2545 100         if (decstate->incomplete_by) {
534 3 100         if (my_key_has_sv) {
535 3           SvREFCNT_dec( my_key.sv );
536             }
537             }
538 2542 100         else if (my_key_has_sv) {
539 2           hv_store_ent(hash, my_key.sv, curval, 0);
540             }
541             else {
542 2545           hv_store(hash, keystr, keylen, curval, 0);
543             }
544             }
545              
546             // Sets incomplete_by.
547 67           SV *_decode_map( pTHX_ decode_ctx* decstate ) {
548 67           union control_byte *control = (union control_byte *) decstate->curbyte;
549              
550 67           HV *hash = newHV();
551 67           sv_2mortal( (SV *) hash );
552              
553 67 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
554 8           ++decstate->curbyte;
555              
556             while (1) {
557 13 100         _RETURN_IF_INCOMPLETE( decstate, 1, NULL );
558              
559 11 100         if (decstate->curbyte[0] == '\xff') {
560 4           ++decstate->curbyte;
561 4           break;
562             }
563              
564 7           _decode_hash_entry( aTHX_ decstate, hash );
565              
566             // TODO: Recursively decref all hash members.
567 7 100         if ( decstate->incomplete_by ) {
568 2           return NULL;
569             }
570 9           }
571             }
572             else {
573 59           SSize_t keycount = _parse_for_uint_len2( aTHX_ decstate );
574 56 100         if ( decstate->incomplete_by ) {
575 5           return NULL;
576             }
577              
578 51 100         if (keycount) {
579 2576 100         while (keycount > 0) {
580 2554           _decode_hash_entry( aTHX_ decstate, hash );
581              
582             // TODO: Recursively decref all hash members.
583 2545 100         if ( decstate->incomplete_by ) {
584 8           return NULL;
585             }
586              
587 2537           --keycount;
588             }
589             }
590             }
591              
592 38           return newRV_inc( (SV *) hash);
593             }
594              
595             //----------------------------------------------------------------------
596              
597             // Taken from RFC 7049:
598 7           double decode_half_float(uint8_t *halfp) {
599 7           int half = (halfp[0] << 8) + halfp[1];
600 7           int exp = (half >> 10) & 0x1f;
601 7           int mant = half & 0x3ff;
602             double val;
603 7 50         if (exp == 0) val = ldexp(mant, -24);
604 7 100         else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
605 6 100         else val = mant == 0 ? INFINITY : NAN;
606 7 100         return half & 0x8000 ? -val : val;
607             }
608              
609 24           static inline float _decode_float_to_host( pTHX_ decode_ctx* decstate, uint8_t *ptr ) {
610 24           *((uint32_t *) decstate->scratch.bytes) = ntohl( *((uint32_t *) ptr) );
611              
612 24           return decstate->scratch.as_float;
613             }
614              
615 63           static inline double _decode_double_to_le( decode_ctx* decstate, uint8_t *ptr ) {
616 63           decstate->scratch.bytes[0] = ptr[7];
617 63           decstate->scratch.bytes[1] = ptr[6];
618 63           decstate->scratch.bytes[2] = ptr[5];
619 63           decstate->scratch.bytes[3] = ptr[4];
620 63           decstate->scratch.bytes[4] = ptr[3];
621 63           decstate->scratch.bytes[5] = ptr[2];
622 63           decstate->scratch.bytes[6] = ptr[1];
623 63           decstate->scratch.bytes[7] = ptr[0];
624              
625 63           return decstate->scratch.as_double;
626             }
627              
628             //----------------------------------------------------------------------
629              
630             // Sets incomplete_by.
631 1201           static inline SV *_decode_str_to_sv( pTHX_ decode_ctx* decstate ) {
632             union numbuf_or_sv string;
633              
634 1201 100         if (_decode_str( aTHX_ decstate, &string )) {
635 4           return string.sv;
636             }
637              
638 1191 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
639              
640 1195           return newSVpvn( string.numbuf.buffer, string.numbuf.num.uv );
641             }
642              
643             // Sets incomplete_by.
644 3949           SV *cbf_decode_one( pTHX_ decode_ctx* decstate ) {
645 3949           SV *ret = NULL;
646              
647 3949 100         _RETURN_IF_INCOMPLETE( decstate, 1, NULL );
648              
649 3938           union control_byte *control = (union control_byte *) decstate->curbyte;
650              
651             // fprintf(stderr, "major type: %d\n", control->pieces.major_type);
652              
653 3938           switch (control->pieces.major_type) {
654             case CBOR_TYPE_UINT:
655 1886           ret = newSVuv( _decode_uint( aTHX_ decstate ) );
656 1882 100         if ( decstate->incomplete_by ) {
657 15           SvREFCNT_dec(ret);
658 188           return NULL;
659             }
660              
661 1867           break;
662             case CBOR_TYPE_NEGINT:
663 43           ret = newSViv( _decode_negint( aTHX_ decstate ) );
664 38 100         if ( decstate->incomplete_by ) {
665 15           SvREFCNT_dec(ret);
666 15           return NULL;
667             }
668              
669 23           break;
670             case CBOR_TYPE_BINARY:
671             case CBOR_TYPE_UTF8:
672 1201           ret = _decode_str_to_sv( aTHX_ decstate );
673 1195 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
674              
675 1122 100         if (SHOULD_VALIDATE_UTF8(decstate, control->pieces.major_type)) {
    100          
676 66 50         _validate_utf8_string_if_needed( aTHX_ decstate, SvPV_nolen(ret), SvCUR(ret));
677              
678             // Always set the UTF8 flag, even if it’s not needed.
679             // This helps ensure that text strings will round-trip
680             // through Perl.
681 65 100         if (decstate->string_decode_mode != CBF_STRING_DECODE_NEVER) SvUTF8_on(ret);
682             }
683              
684 1121           break;
685             case CBOR_TYPE_ARRAY:
686 171           ret = _decode_array( aTHX_ decstate );
687 119 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
688              
689 85           break;
690             case CBOR_TYPE_MAP:
691 67           ret = _decode_map( aTHX_ decstate );
692 55 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
693              
694 38           break;
695             case CBOR_TYPE_TAG:
696              
697 198 100         if (control->pieces.length_type == CBOR_LENGTH_INDEFINITE) {
698 1           _croak_invalid_control( aTHX_ decstate );
699             }
700              
701 197           UV tagnum = _parse_for_uint_len2( aTHX_ decstate );
702 194 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
703              
704 179           U8 value_major_type = ((union control_byte *) decstate->curbyte)->pieces.major_type;
705              
706 191 100         if (tagnum == CBOR_TAG_SHAREDREF && decstate->reflist) {
    100          
707 12 50         if (value_major_type != CBOR_TYPE_UINT) {
708             char tmpl[255];
709 0 0         my_snprintf( tmpl, sizeof(tmpl), "Shared ref type must be uint, not %%u (%%s)!" );
710 0           croak(tmpl, value_major_type, MAJOR_TYPE_DESCRIPTION[value_major_type]);
711             }
712              
713 12           UV refnum = _parse_for_uint_len2( aTHX_ decstate );
714 12 50         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
715              
716 12 50         if (refnum >= decstate->reflistlen) {
717 0           _croak("Missing shareable!");
718             }
719              
720 12           ret = decstate->reflist[refnum];
721 12           SvREFCNT_inc(ret);
722             }
723             else {
724 167           ret = cbf_decode_one( aTHX_ decstate );
725 167 100         _RETURN_IF_SET_INCOMPLETE(decstate, NULL);
726              
727 162 100         if (tagnum == CBOR_TAG_INDIRECTION) {
728 17           ret = newRV_noinc(ret);
729             }
730 145 100         else if (tagnum == CBOR_TAG_SHAREABLE && decstate->reflist) {
    100          
731 12           ++decstate->reflistlen;
732 12 50         Renew( decstate->reflist, decstate->reflistlen, void * );
733              
734 12           decstate->reflist[ decstate->reflistlen - 1 ] = (SV *) ret;
735             }
736              
737 133 100         else if (decstate->tag_handler) {
738 102           HV *my_tag_handler = decstate->tag_handler;
739              
740 102           SV **handler_cr = hv_fetch( my_tag_handler, (char *) &tagnum, sizeof(UV), 0 );
741              
742 102 100         if (handler_cr && *handler_cr && SvOK(*handler_cr)) {
    50          
    100          
    50          
    50          
743 100           ret = cbf_call_scalar_with_arguments( aTHX_ *handler_cr, 1, &ret );
744             }
745             else {
746 102           _warn_unhandled_tag( aTHX_ tagnum, value_major_type );
747             }
748             }
749             else {
750 31           _warn_unhandled_tag( aTHX_ tagnum, value_major_type );
751             }
752             }
753              
754 174           break;
755             case CBOR_TYPE_OTHER:
756 372           switch (control->u8) {
757             case CBOR_FALSE:
758 3           ret = newSVsv( cbf_get_false() );
759 3           ++decstate->curbyte;
760 3           break;
761              
762             case CBOR_TRUE:
763 6           ret = newSVsv( cbf_get_true() );
764 6           ++decstate->curbyte;
765 6           break;
766              
767             case CBOR_NULL:
768             case CBOR_UNDEFINED:
769 230           ret = &PL_sv_undef;
770 230           ++decstate->curbyte;
771 230           break;
772              
773             case CBOR_HALF_FLOAT:
774 9 100         _RETURN_IF_INCOMPLETE( decstate, 3, NULL );
775              
776 7           ret = newSVnv( decode_half_float( (uint8_t *) (1 + decstate->curbyte) ) );
777              
778 7           decstate->curbyte += 3;
779 7           break;
780              
781             case CBOR_FLOAT:
782 28 100         _RETURN_IF_INCOMPLETE( decstate, 5, NULL );
783              
784             float decoded_flt;
785              
786             #if IS_LITTLE_ENDIAN
787 24           decoded_flt = _decode_float_to_host( aTHX_ decstate, (uint8_t *) (1 + decstate->curbyte ) );
788             #else
789             decoded_flt = *( (float *) (1 + decstate->curbyte) );
790             #endif
791              
792 24           ret = newSVnv( (NV) decoded_flt );
793              
794 24           decstate->curbyte += 5;
795 24           break;
796              
797             case CBOR_DOUBLE:
798 71 100         _RETURN_IF_INCOMPLETE( decstate, 9, NULL );
799              
800             double decoded_dbl;
801              
802             #if IS_LITTLE_ENDIAN
803 63           decoded_dbl = _decode_double_to_le( decstate, (uint8_t *) (1 + decstate->curbyte ) );
804             #else
805             decoded_dbl = *( (double *) (1 + decstate->curbyte) );
806             #endif
807              
808 63           ret = newSVnv( (NV) decoded_dbl );
809              
810 63           decstate->curbyte += 9;
811 63           break;
812              
813             default:
814 25           _croak_invalid_control( aTHX_ decstate );
815             }
816              
817 333           break;
818              
819             default:
820 0           _croak("Unknown type!");
821             }
822              
823 3840           return ret;
824             }
825              
826             /*
827             * Possible states:
828             *
829             * 1) We’re initializing.
830             * 2) We just concat’ed two SVPVs (same as initializing).
831             * 3) We just shortened from the beginning.
832             */
833              
834 629           void renew_decode_state_buffer( pTHX_ decode_ctx *decode_state, SV *cbor ) {
835 629           STRLEN cborlen = SvCUR(cbor);
836              
837 629           char *cborstr = SvPVX(cbor);
838              
839             STRLEN offset;
840 629 100         if (decode_state->curbyte == NULL) {
841 599           offset = 0;
842             }
843             else {
844 30           offset = decode_state->curbyte - decode_state->start;
845             }
846              
847 629           decode_state->start = cborstr;
848 629           decode_state->size = cborlen;
849 629           decode_state->curbyte = cborstr + offset;
850 629           decode_state->end = cborstr + cborlen;
851 629           }
852              
853 18           void advance_decode_state_buffer( pTHX_ decode_ctx *decode_state ) {
854 18           STRLEN diff = decode_state->curbyte - decode_state->start;
855              
856 18           decode_state->start = decode_state->curbyte;
857 18           decode_state->size -= diff;
858 18           }
859              
860 579           decode_ctx* create_decode_state( pTHX_ SV *cbor, HV *tag_handler, UV flags ) {
861             decode_ctx *decode_state;
862 579           Newx( decode_state, 1, decode_ctx );
863              
864 579           decode_state->curbyte = NULL;
865              
866 579 100         if (cbor) {
867 472           renew_decode_state_buffer( aTHX_ decode_state, cbor );
868             }
869              
870 579           decode_state->tag_handler = tag_handler;
871 579 50         if (NULL != tag_handler) {
872 0           SvREFCNT_inc((SV *) tag_handler);
873             }
874              
875 579           decode_state->reflist = NULL;
876 579           decode_state->reflistlen = 0;
877 579           decode_state->flags = flags;
878 579           decode_state->incomplete_by = 0;
879              
880 579           decode_state->string_decode_mode = CBF_STRING_DECODE_CBOR;
881              
882 579 50         if (flags & CBF_FLAG_PRESERVE_REFERENCES) {
883 0           ensure_reflist_exists( aTHX_ decode_state );
884             }
885              
886 579           return decode_state;
887             }
888              
889 4           void ensure_reflist_exists( pTHX_ decode_ctx* decode_state) {
890 4 50         if (NULL == decode_state->reflist) {
891 4           Newx( decode_state->reflist, 0, void * );
892             }
893 4           }
894              
895 583           void delete_reflist( pTHX_ decode_ctx* decode_state) {
896 583 100         if (NULL != decode_state->reflist) {
897 4           Safefree(decode_state->reflist);
898 4           decode_state->reflist = NULL;
899 4           decode_state->reflistlen = 0;
900             }
901 583           }
902              
903 4           void reset_reflist_if_needed( pTHX_ decode_ctx* decode_state) {
904 4 100         if (decode_state->reflistlen) {
905 2           delete_reflist( aTHX_ decode_state );
906 2           ensure_reflist_exists( aTHX_ decode_state );
907             }
908 4           }
909              
910 579           void free_decode_state( pTHX_ decode_ctx* decode_state) {
911 579           delete_reflist( aTHX_ decode_state );
912              
913 579 100         if (NULL != decode_state->tag_handler) {
914 102           SvREFCNT_dec((SV *) decode_state->tag_handler);
915 102           decode_state->tag_handler = NULL;
916             }
917              
918 579           Safefree(decode_state);
919 579           }
920              
921 590           SV *cbf_decode_document( pTHX_ decode_ctx *decode_state ) {
922 590           SV *RETVAL = cbf_decode_one( aTHX_ decode_state );
923              
924 530 100         if (decode_state->incomplete_by) {
925 146           _croak_incomplete( aTHX_ decode_state );
926             }
927              
928 384 100         if (decode_state->curbyte != decode_state->end) {
929 1           STRLEN bytes_count = decode_state->end - decode_state->curbyte;
930              
931             char numstr[24];
932 1           _uv_to_str(bytes_count, numstr, 24);
933              
934 1           char * words[2] = { numstr, NULL };
935              
936 1           call_argv("CBOR::Free::_warn_decode_leftover", G_DISCARD, words);
937             }
938              
939 384           return RETVAL;
940             }
941              
942 463           SV *cbf_decode( pTHX_ SV *cbor, HV *tag_handler, UV flags ) {
943              
944 463           decode_ctx *decode_state = create_decode_state( aTHX_ cbor, tag_handler, flags);
945              
946 463           SV *RETVAL = cbf_decode_document( aTHX_ decode_state );
947              
948 268           free_decode_state( aTHX_ decode_state);
949              
950 268           return RETVAL;
951             }