#ifndef SRL_DECODER_H_ #define SRL_DECODER_H_ #include "EXTERN.h" #include "perl.h" #include "assert.h" typedef struct PTABLE * ptable_ptr; typedef struct { unsigned char *buf_start; /* ptr to "physical" start of input buffer */ unsigned char *buf_end; /* ptr to end of input buffer */ unsigned char *pos; /* ptr to current position within input buffer */ unsigned char *save_pos; /* used for COPY tags */ STRLEN buf_len; U32 flags; /* flag-like options: See F_* defines in srl_decoder.c */ UV max_recursion_depth; /* Configurable limit on the number of recursive calls we're willing to make */ UV max_num_hash_entries; /* Configured maximum number of acceptable entries in a hash */ ptable_ptr ref_seenhash; /* ptr table for avoiding circular refs */ ptable_ptr ref_stashes; /* ptr table for tracking stashes we will bless into - key: ofs, value: stash */ ptable_ptr ref_bless_av; /* ptr table for tracking which objects need to be bless - key: ofs, value: mortal AV (of refs) */ AV* weakref_av; UV bytes_consumed; UV recursion_depth; /* Recursion depth of current decoder */ U8 proto_version_and_flags; } srl_decoder_t; /* constructor; don't need destructor, this sets up a callback */ srl_decoder_t *srl_build_decoder_struct(pTHX_ HV *opt); /* main routine */ SV *srl_decode_into(pTHX_ srl_decoder_t *dec, SV *src, SV *into, UV start_offset); /* Explicit destructor */ void srl_destroy_decoder(pTHX_ srl_decoder_t *dec); /* destructor hook - called automagically */ void srl_decoder_destructor_hook(pTHX_ void *p); #define BUF_POS(dec) ((dec)->pos) #define BUF_SPACE(dec) ((dec)->buf_end - (dec)->pos) #define BUF_POS_OFS(dec) ((dec)->pos - (dec)->buf_start) #define BUF_SIZE(dec) ((dec)->buf_end - (dec)->buf_start) #define BUF_NOT_DONE(dec) ((dec)->pos < (dec)->buf_end) #define BUF_DONE(dec) ((dec)->pos >= (dec)->buf_end) #define SRL_BASE_ERROR_FORMAT "Sereal: Error in %s line %u: " #define SRL_BASE_ERROR_ARGS __FILE__, __LINE__ #define SRL_ERROR(msg) croak(SRL_BASE_ERROR_FORMAT "%s", SRL_BASE_ERROR_ARGS, (msg)) #define SRL_ERRORf1(fmt,var) croak(SRL_BASE_ERROR_FORMAT fmt, SRL_BASE_ERROR_ARGS, (var)) #define SRL_ERRORf2(fmt,var1,var2) croak(SRL_BASE_ERROR_FORMAT fmt, SRL_BASE_ERROR_ARGS, (var1),(var2)) #define SRL_ERRORf3(fmt,var1,var2,var3) croak(SRL_BASE_ERROR_FORMAT fmt, SRL_BASE_ERROR_ARGS, (var1),(var2),(var3)) #define SRL_ERRORf4(fmt,var1,var2,var3,var4) croak(SRL_BASE_ERROR_FORMAT fmt, SRL_BASE_ERROR_ARGS, (var1),(var2),(var3),(var4)) #define SRL_ERROR_UNIMPLEMENTED(dec,tag,str) \ SRL_ERRORf3("Tag %u %s is unimplemented at ofs: %d", (tag), (str), BUF_POS_OFS(dec)) #define SRL_ERROR_UNTERMINATED(dec,tag,str) \ SRL_ERRORf4("Tag SRL_HDR_%s %s was not terminated properly at ofs %lu with %lu to go", \ tag_name[(tag) & 127], (str), (dec)->pos - (dec)->buf_start, (dec)->buf_end - (dec)->pos) #define SRL_ERROR_BAD_COPY(dec, tag) \ SRL_ERRORf1("While processing tag SRL_HDR_%s encountered a bad COPY tag", tag_name[(tag) & 127]) #define SRL_ERROR_UNEXPECTED(dec, tag, msg) \ SRL_ERRORf2("Unexpected tag %s while expecting %s", tag_name[(tag || *(dec)->pos) & 127], msg) #define SRL_ERROR_REFUSE_OBJECT() \ SRL_ERROR("Encountered object in input, but the 'refuse_objects' option is in effect"); #define SRL_ERROR_PANIC(dec, msg) SRL_ERRORf1("Panic: %s", msg); /* If set, the decoder struct needs to be cleared instead of freed at * the end of a deserialization operation */ #define SRL_F_REUSE_DECODER 1UL /* If set, then the decoder destructor was already pushed to the * callback stack */ #define SRL_F_DECODER_DESTRUCTOR_OK 2UL /* Non-persistent flag! */ #define SRL_F_DECODER_NEEDS_FINALIZE 4UL /* Non-persistent flag! */ #define SRL_F_DECODER_DECOMPRESS_SNAPPY 8UL /* Persistent flag: Make the decoder REFUSE compressed documents */ #define SRL_F_DECODER_REFUSE_SNAPPY 16UL /* Persistent flag: Make the decoder REFUSE opjects */ #define SRL_F_DECODER_REFUSE_OBJECTS 32UL /* Persistent flag: Make the decoder validate UTT8 strings */ #define SRL_F_DECODER_VALIDATE_UTF8 64UL #define SRL_DEC_HAVE_OPTION(dec, flag_num) ((dec)->flags & flag_num) #define SRL_DEC_SET_OPTION(dec, flag_num) ((dec)->flags |= flag_num) #define SRL_DEC_UNSET_OPTION(dec, flag_num) ((dec)->flags &= ~flag_num) #define SRL_DEC_VOLATILE_FLAGS (SRL_F_DECODER_NEEDS_FINALIZE|SRL_F_DECODER_DECOMPRESS_SNAPPY) #define SRL_DEC_RESET_VOLATILE_FLAGS(dec) ((dec)->flags &= ~SRL_DEC_VOLATILE_FLAGS) /* =for autoupdater start * NOTE this section is autoupdated by author_tools/update_from_header.pl */ static const char * const tag_name[] = { "POS_0", /* 0 0x00 0b00000000 */ "POS_1", /* 1 0x01 0b00000001 */ "POS_2", /* 2 0x02 0b00000010 */ "POS_3", /* 3 0x03 0b00000011 */ "POS_4", /* 4 0x04 0b00000100 */ "POS_5", /* 5 0x05 0b00000101 */ "POS_6", /* 6 0x06 0b00000110 */ "POS_7", /* "\a" 7 0x07 0b00000111 */ "POS_8", /* "\b" 8 0x08 0b00001000 */ "POS_9", /* "\t" 9 0x09 0b00001001 */ "POS_10", /* "\n" 10 0x0a 0b00001010 */ "POS_11", /* 11 0x0b 0b00001011 */ "POS_12", /* "\f" 12 0x0c 0b00001100 */ "POS_13", /* "\r" 13 0x0d 0b00001101 */ "POS_14", /* 14 0x0e 0b00001110 */ "POS_15", /* 15 0x0f 0b00001111 */ "NEG_16", /* 16 0x10 0b00010000 */ "NEG_15", /* 17 0x11 0b00010001 */ "NEG_14", /* 18 0x12 0b00010010 */ "NEG_13", /* 19 0x13 0b00010011 */ "NEG_12", /* 20 0x14 0b00010100 */ "NEG_11", /* 21 0x15 0b00010101 */ "NEG_10", /* 22 0x16 0b00010110 */ "NEG_9", /* 23 0x17 0b00010111 */ "NEG_8", /* 24 0x18 0b00011000 */ "NEG_7", /* 25 0x19 0b00011001 */ "NEG_6", /* 26 0x1a 0b00011010 */ "NEG_5", /* "\e" 27 0x1b 0b00011011 */ "NEG_4", /* 28 0x1c 0b00011100 */ "NEG_3", /* 29 0x1d 0b00011101 */ "NEG_2", /* 30 0x1e 0b00011110 */ "NEG_1", /* 31 0x1f 0b00011111 */ "VARINT", /* " " 32 0x20 0b00100000 */ "ZIGZAG", /* "!" 33 0x21 0b00100001 */ "FLOAT", /* "\"" 34 0x22 0b00100010 */ "DOUBLE", /* "#" 35 0x23 0b00100011 */ "LONG_DOUBLE", /* "\$" 36 0x24 0b00100100 */ "UNDEF", /* "%" 37 0x25 0b00100101 */ "BINARY", /* "&" 38 0x26 0b00100110 */ "STR_UTF8", /* "'" 39 0x27 0b00100111 */ "REFN", /* "(" 40 0x28 0b00101000 */ "REFP", /* ")" 41 0x29 0b00101001 */ "HASH", /* "*" 42 0x2a 0b00101010 */ "ARRAY", /* "+" 43 0x2b 0b00101011 */ "OBJECT", /* "," 44 0x2c 0b00101100 */ "OBJECTV", /* "-" 45 0x2d 0b00101101 */ "ALIAS", /* "." 46 0x2e 0b00101110 */ "COPY", /* "/" 47 0x2f 0b00101111 */ "WEAKEN", /* "0" 48 0x30 0b00110000 */ "REGEXP", /* "1" 49 0x31 0b00110001 */ "RESERVED_0", /* "2" 50 0x32 0b00110010 */ "RESERVED_1", /* "3" 51 0x33 0b00110011 */ "RESERVED_2", /* "4" 52 0x34 0b00110100 */ "RESERVED_3", /* "5" 53 0x35 0b00110101 */ "RESERVED_4", /* "6" 54 0x36 0b00110110 */ "RESERVED_5", /* "7" 55 0x37 0b00110111 */ "RESERVED_6", /* "8" 56 0x38 0b00111000 */ "RESERVED_7", /* "9" 57 0x39 0b00111001 */ "FALSE", /* ":" 58 0x3a 0b00111010 */ "TRUE", /* ";" 59 0x3b 0b00111011 */ "MANY", /* "<" 60 0x3c 0b00111100 */ "PACKET_START", /* "=" 61 0x3d 0b00111101 */ "EXTEND", /* ">" 62 0x3e 0b00111110 */ "PAD", /* "?" 63 0x3f 0b00111111 */ "ARRAYREF_0", /* "\@" 64 0x40 0b01000000 */ "ARRAYREF_1", /* "A" 65 0x41 0b01000001 */ "ARRAYREF_2", /* "B" 66 0x42 0b01000010 */ "ARRAYREF_3", /* "C" 67 0x43 0b01000011 */ "ARRAYREF_4", /* "D" 68 0x44 0b01000100 */ "ARRAYREF_5", /* "E" 69 0x45 0b01000101 */ "ARRAYREF_6", /* "F" 70 0x46 0b01000110 */ "ARRAYREF_7", /* "G" 71 0x47 0b01000111 */ "ARRAYREF_8", /* "H" 72 0x48 0b01001000 */ "ARRAYREF_9", /* "I" 73 0x49 0b01001001 */ "ARRAYREF_10", /* "J" 74 0x4a 0b01001010 */ "ARRAYREF_11", /* "K" 75 0x4b 0b01001011 */ "ARRAYREF_12", /* "L" 76 0x4c 0b01001100 */ "ARRAYREF_13", /* "M" 77 0x4d 0b01001101 */ "ARRAYREF_14", /* "N" 78 0x4e 0b01001110 */ "ARRAYREF_15", /* "O" 79 0x4f 0b01001111 */ "HASHREF_0", /* "P" 80 0x50 0b01010000 */ "HASHREF_1", /* "Q" 81 0x51 0b01010001 */ "HASHREF_2", /* "R" 82 0x52 0b01010010 */ "HASHREF_3", /* "S" 83 0x53 0b01010011 */ "HASHREF_4", /* "T" 84 0x54 0b01010100 */ "HASHREF_5", /* "U" 85 0x55 0b01010101 */ "HASHREF_6", /* "V" 86 0x56 0b01010110 */ "HASHREF_7", /* "W" 87 0x57 0b01010111 */ "HASHREF_8", /* "X" 88 0x58 0b01011000 */ "HASHREF_9", /* "Y" 89 0x59 0b01011001 */ "HASHREF_10", /* "Z" 90 0x5a 0b01011010 */ "HASHREF_11", /* "[" 91 0x5b 0b01011011 */ "HASHREF_12", /* "\\" 92 0x5c 0b01011100 */ "HASHREF_13", /* "]" 93 0x5d 0b01011101 */ "HASHREF_14", /* "^" 94 0x5e 0b01011110 */ "HASHREF_15", /* "_" 95 0x5f 0b01011111 */ "SHORT_BINARY_0", /* "`" 96 0x60 0b01100000 */ "SHORT_BINARY_1", /* "a" 97 0x61 0b01100001 */ "SHORT_BINARY_2", /* "b" 98 0x62 0b01100010 */ "SHORT_BINARY_3", /* "c" 99 0x63 0b01100011 */ "SHORT_BINARY_4", /* "d" 100 0x64 0b01100100 */ "SHORT_BINARY_5", /* "e" 101 0x65 0b01100101 */ "SHORT_BINARY_6", /* "f" 102 0x66 0b01100110 */ "SHORT_BINARY_7", /* "g" 103 0x67 0b01100111 */ "SHORT_BINARY_8", /* "h" 104 0x68 0b01101000 */ "SHORT_BINARY_9", /* "i" 105 0x69 0b01101001 */ "SHORT_BINARY_10", /* "j" 106 0x6a 0b01101010 */ "SHORT_BINARY_11", /* "k" 107 0x6b 0b01101011 */ "SHORT_BINARY_12", /* "l" 108 0x6c 0b01101100 */ "SHORT_BINARY_13", /* "m" 109 0x6d 0b01101101 */ "SHORT_BINARY_14", /* "n" 110 0x6e 0b01101110 */ "SHORT_BINARY_15", /* "o" 111 0x6f 0b01101111 */ "SHORT_BINARY_16", /* "p" 112 0x70 0b01110000 */ "SHORT_BINARY_17", /* "q" 113 0x71 0b01110001 */ "SHORT_BINARY_18", /* "r" 114 0x72 0b01110010 */ "SHORT_BINARY_19", /* "s" 115 0x73 0b01110011 */ "SHORT_BINARY_20", /* "t" 116 0x74 0b01110100 */ "SHORT_BINARY_21", /* "u" 117 0x75 0b01110101 */ "SHORT_BINARY_22", /* "v" 118 0x76 0b01110110 */ "SHORT_BINARY_23", /* "w" 119 0x77 0b01110111 */ "SHORT_BINARY_24", /* "x" 120 0x78 0b01111000 */ "SHORT_BINARY_25", /* "y" 121 0x79 0b01111001 */ "SHORT_BINARY_26", /* "z" 122 0x7a 0b01111010 */ "SHORT_BINARY_27", /* "{" 123 0x7b 0b01111011 */ "SHORT_BINARY_28", /* "|" 124 0x7c 0b01111100 */ "SHORT_BINARY_29", /* "}" 125 0x7d 0b01111101 */ "SHORT_BINARY_30", /* "~" 126 0x7e 0b01111110 */ "SHORT_BINARY_31" /* 127 0x7f 0b01111111 */ }; /* * NOTE the above section is auto-updated by author_tools/update_from_header.pl =for autoupdater stop */ #endif