Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/tvbuff_hpackhuff.c
Line
Count
Source
1
/* @file
2
 * Decompression of the Huffman encoding used for HTTP fields in HPACK (HTTP/2)
3
 * and QPACK (HTTP/3)
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/tvbuff.h>
15
#include <epan/nghttp2_hd_huffman.h>
16
17
static wmem_strbuf_t *
18
get_hpack_huffman_strbuf(wmem_allocator_t *scope, const uint8_t *ptr, size_t len)
19
0
{
20
0
    wmem_strbuf_t *strbuf;
21
0
    strbuf = wmem_strbuf_new_sized(scope, len + 1);
22
23
0
    nghttp2_huff_decode node = {0, 0};
24
0
    const nghttp2_huff_decode *nodep = &node;
25
26
0
    while (len > 0) {
27
0
        uint8_t ch = *ptr++;
28
29
0
        nodep = &huff_decode_table[nodep->fstate & 0x1ff][ch >> 4];
30
0
        if (nodep->fstate & NGHTTP2_HUFF_SYM) {
31
0
            wmem_strbuf_append_c(strbuf, nodep->sym);
32
0
        }
33
34
0
        nodep = &huff_decode_table[nodep->fstate & 0x1ff][ch & 0xf];
35
0
        if (nodep->fstate & NGHTTP2_HUFF_SYM) {
36
0
            wmem_strbuf_append_c(strbuf, nodep->sym);
37
0
        }
38
39
0
        len--;
40
0
    }
41
42
0
    if (!(nodep->fstate & NGHTTP2_HUFF_ACCEPTED)) {
43
0
        wmem_strbuf_destroy(strbuf);
44
0
        return NULL;
45
0
    }
46
47
0
    return strbuf;
48
0
}
49
50
wmem_strbuf_t *
51
tvb_get_hpack_huffman_strbuf(wmem_allocator_t *scope, tvbuff_t *tvb, const unsigned offset, const unsigned len)
52
0
{
53
0
    return get_hpack_huffman_strbuf(scope, tvb_get_ptr(tvb, offset, len), len);
54
0
}
55
56
tvbuff_t*
57
tvb_child_uncompress_hpack_huff(tvbuff_t* parent, unsigned offset, unsigned length)
58
0
{
59
0
    tvbuff_t* tvb = NULL;
60
0
    wmem_strbuf_t *strbuf;
61
0
    char* data;
62
0
    size_t len;
63
64
0
    strbuf = tvb_get_hpack_huffman_strbuf(NULL, parent, offset, length);
65
66
0
    if (strbuf) {
67
0
        len = wmem_strbuf_get_len(strbuf);
68
0
        data = wmem_strbuf_finalize(strbuf);
69
70
0
        tvb = tvb_new_child_real_data(parent, (const uint8_t*)data, (unsigned)len, (unsigned)len);
71
72
0
        tvb_set_free_cb(tvb, g_free);
73
0
    }
74
75
0
    return tvb;
76
0
}