… | |
… | |
584 | SvREFCNT_dec (av); |
584 | SvREFCNT_dec (av); |
585 | DEC_DEC_DEPTH; |
585 | DEC_DEC_DEPTH; |
586 | return &PL_sv_undef; |
586 | return &PL_sv_undef; |
587 | } |
587 | } |
588 | |
588 | |
|
|
589 | static void |
|
|
590 | decode_he (dec_t *dec, HV *hv) |
|
|
591 | { |
|
|
592 | // for speed reasons, we specialcase single-string |
|
|
593 | // byte or utf-8 strings as keys. |
|
|
594 | |
|
|
595 | if (*dec->cur >= 0x40 && *dec->cur <= 0x40 + 27) |
|
|
596 | { |
|
|
597 | I32 len = decode_uint (dec); |
|
|
598 | char *key = (char *)dec->cur; |
|
|
599 | |
|
|
600 | dec->cur += len; |
|
|
601 | |
|
|
602 | hv_store (hv, key, len, decode_sv (dec), 0); |
|
|
603 | } |
|
|
604 | else if (*dec->cur >= 0x60 && *dec->cur <= 0x60 + 27) |
|
|
605 | { |
|
|
606 | I32 len = decode_uint (dec); |
|
|
607 | char *key = (char *)dec->cur; |
|
|
608 | |
|
|
609 | dec->cur += len; |
|
|
610 | |
|
|
611 | hv_store (hv, key, -len, decode_sv (dec), 0); |
|
|
612 | } |
|
|
613 | else |
|
|
614 | { |
|
|
615 | SV *k = decode_sv (dec); |
|
|
616 | SV *v = decode_sv (dec); |
|
|
617 | |
|
|
618 | hv_store_ent (hv, k, v, 0); |
|
|
619 | SvREFCNT_dec (k); |
|
|
620 | } |
|
|
621 | } |
|
|
622 | |
589 | static SV * |
623 | static SV * |
590 | decode_hv (dec_t *dec) |
624 | decode_hv (dec_t *dec) |
591 | { |
625 | { |
592 | HV *hv = newHV (); |
626 | HV *hv = newHV (); |
593 | |
627 | |
… | |
… | |
605 | { |
639 | { |
606 | ++dec->cur; |
640 | ++dec->cur; |
607 | break; |
641 | break; |
608 | } |
642 | } |
609 | |
643 | |
610 | SV *k = decode_sv (dec); |
644 | decode_he (dec, hv); |
611 | SV *v = decode_sv (dec); |
|
|
612 | |
|
|
613 | hv_store_ent (hv, k, v, 0); |
|
|
614 | SvREFCNT_dec (k); |
|
|
615 | } |
645 | } |
616 | } |
646 | } |
617 | else |
647 | else |
618 | { |
648 | { |
619 | int len = decode_uint (dec); |
649 | int pairs = decode_uint (dec); |
620 | |
650 | |
621 | while (len--) |
651 | while (pairs--) |
622 | { |
652 | decode_he (dec, hv); |
623 | SV *k = decode_sv (dec); |
|
|
624 | SV *v = decode_sv (dec); |
|
|
625 | |
|
|
626 | hv_store_ent (hv, k, v, 0); |
|
|
627 | SvREFCNT_dec (k); |
|
|
628 | } |
|
|
629 | } |
653 | } |
630 | |
654 | |
631 | DEC_DEC_DEPTH; |
655 | DEC_DEC_DEPTH; |
632 | return newRV_noinc ((SV *)hv); |
656 | return newRV_noinc ((SV *)hv); |
633 | |
657 | |
… | |
… | |
844 | static SV * |
868 | static SV * |
845 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
869 | decode_cbor (SV *string, CBOR *cbor, char **offset_return) |
846 | { |
870 | { |
847 | dec_t dec; |
871 | dec_t dec; |
848 | SV *sv; |
872 | SV *sv; |
|
|
873 | STRLEN len; |
|
|
874 | char *data = SvPVbyte (string, len); |
849 | |
875 | |
850 | /* work around bugs in 5.10 where manipulating magic values |
|
|
851 | * makes perl ignore the magic in subsequent accesses. |
|
|
852 | * also make a copy of non-PV values, to get them into a clean |
|
|
853 | * state (SvPV should do that, but it's buggy, see below). |
|
|
854 | */ |
|
|
855 | /*SvGETMAGIC (string);*/ |
|
|
856 | if (SvMAGICAL (string) || !SvPOK (string)) |
|
|
857 | string = sv_2mortal (newSVsv (string)); |
|
|
858 | |
|
|
859 | SvUPGRADE (string, SVt_PV); |
|
|
860 | |
|
|
861 | /* work around a bug in perl 5.10, which causes SvCUR to fail an |
|
|
862 | * assertion with -DDEBUGGING, although SvCUR is documented to |
|
|
863 | * return the xpv_cur field which certainly exists after upgrading. |
|
|
864 | * according to nicholas clark, calling SvPOK fixes this. |
|
|
865 | * But it doesn't fix it, so try another workaround, call SvPV_nolen |
|
|
866 | * and hope for the best. |
|
|
867 | * Damnit, SvPV_nolen still trips over yet another assertion. This |
|
|
868 | * assertion business is seriously broken, try yet another workaround |
|
|
869 | * for the broken -DDEBUGGING. |
|
|
870 | */ |
|
|
871 | { |
|
|
872 | #ifdef DEBUGGING |
|
|
873 | STRLEN offset = SvOK (string) ? sv_len (string) : 0; |
|
|
874 | #else |
|
|
875 | STRLEN offset = SvCUR (string); |
|
|
876 | #endif |
|
|
877 | |
|
|
878 | if (offset > cbor->max_size && cbor->max_size) |
876 | if (len > cbor->max_size && cbor->max_size) |
879 | croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu", |
877 | croak ("attempted decode of CBOR text of %lu bytes size, but max_size is set to %lu", |
880 | (unsigned long)SvCUR (string), (unsigned long)cbor->max_size); |
878 | (unsigned long)len, (unsigned long)cbor->max_size); |
881 | } |
|
|
882 | |
|
|
883 | sv_utf8_downgrade (string, 0); |
|
|
884 | |
879 | |
885 | dec.cbor = *cbor; |
880 | dec.cbor = *cbor; |
886 | dec.cur = (U8 *)SvPVX (string); |
881 | dec.cur = (U8 *)data; |
887 | dec.end = (U8 *)SvEND (string); |
882 | dec.end = (U8 *)data + len; |
888 | dec.err = 0; |
883 | dec.err = 0; |
889 | dec.depth = 0; |
884 | dec.depth = 0; |
890 | |
885 | |
891 | sv = decode_sv (&dec); |
886 | sv = decode_sv (&dec); |
892 | |
887 | |
… | |
… | |
898 | dec.err = "garbage after CBOR object"; |
893 | dec.err = "garbage after CBOR object"; |
899 | |
894 | |
900 | if (dec.err) |
895 | if (dec.err) |
901 | { |
896 | { |
902 | SvREFCNT_dec (sv); |
897 | SvREFCNT_dec (sv); |
903 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)SvPVX (string), (int)(uint8_t)*dec.cur); |
898 | croak ("%s, at offset %d (octet 0x%02x)", dec.err, dec.cur - (U8 *)data, (int)(uint8_t)*dec.cur); |
904 | } |
899 | } |
905 | |
900 | |
906 | sv = sv_2mortal (sv); |
901 | sv = sv_2mortal (sv); |
907 | |
902 | |
908 | return sv; |
903 | return sv; |