| 910 | } |
| 911 | |
| 912 | int |
| 913 | QPACK::_decode_header(const uint8_t *header_block, size_t header_block_len, HTTPHdr &hdr) |
| 914 | { |
| 915 | const uint8_t *pos = header_block; |
| 916 | size_t remain_len = header_block_len; |
| 917 | int64_t ret; |
| 918 | |
| 919 | // Decode Header Data Prefix |
| 920 | uint64_t tmp; |
| 921 | if ((ret = xpack_decode_integer(tmp, pos, pos + remain_len, 8)) < 0 && tmp > 0xFFFF) { |
| 922 | return -1; |
| 923 | } |
| 924 | pos += ret; |
| 925 | uint16_t largest_reference = tmp; |
| 926 | |
| 927 | uint64_t delta_base_index; |
| 928 | uint16_t base_index; |
| 929 | if ((ret = xpack_decode_integer(delta_base_index, pos, pos + remain_len, 7)) < 0 && delta_base_index < 0xFFFF) { |
| 930 | return -2; |
| 931 | } |
| 932 | |
| 933 | if (pos[0] & 0x80) { |
| 934 | if (delta_base_index == 0) { |
| 935 | return -3; |
| 936 | } |
| 937 | base_index = largest_reference - delta_base_index; |
| 938 | } else { |
| 939 | base_index = largest_reference + delta_base_index; |
| 940 | } |
| 941 | pos += ret; |
| 942 | |
| 943 | uint32_t decoded_header_list_size = 0; |
| 944 | |
| 945 | // Decode Instructions |
| 946 | while (pos < header_block + header_block_len) { |
| 947 | uint32_t header_len = 0; |
| 948 | |
| 949 | if (pos[0] & 0x80) { // Index Header Field |
| 950 | ret = this->_decode_indexed_header_field(base_index, pos, remain_len, hdr, header_len); |
| 951 | } else if (pos[0] & 0x40) { // Literal Header Field With Name Reference |
| 952 | ret = this->_decode_literal_header_field_with_name_ref(base_index, pos, remain_len, hdr, header_len); |
| 953 | } else if (pos[0] & 0x20) { // Literal Header Field Without Name Reference |
| 954 | ret = this->_decode_literal_header_field_without_name_ref(pos, remain_len, hdr, header_len); |
| 955 | } else if (pos[0] & 0x10) { // Indexed Header Field With Post-Base Index |
| 956 | ret = this->_decode_indexed_header_field_with_postbase_index(base_index, pos, remain_len, hdr, header_len); |
| 957 | } else { // Literal Header Field With Post-Base Name Reference |
| 958 | ret = this->_decode_literal_header_field_with_postbase_name_ref(base_index, pos, remain_len, hdr, header_len); |
| 959 | } |
| 960 | |
| 961 | if (ret < 0) { |
| 962 | break; |
| 963 | } |
| 964 | |
| 965 | decoded_header_list_size += header_len; |
| 966 | if (decoded_header_list_size > this->_max_field_section_size) { |
| 967 | ret = -2; |
| 968 | break; |
| 969 | } |
no test coverage detected