3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <brotli/decode.h>
25 * 512KiB is the buffer size used by the brotli tool, so we
28 #define TVB_BROTLI_BUFSIZ (1 << 19)
31 brotli_g_malloc_wrapper(void *opaque _U_
, size_t size
)
33 return g_malloc(size
);
37 brotli_g_free_wrapper(void *opaque _U_
, void *address
)
43 * Uncompresses a brotli compressed packet inside a message of tvb at offset with
44 * length comprlen. Returns an uncompressed tvbuffer if uncompression
45 * succeeded or NULL if uncompression failed.
49 tvb_uncompress_brotli(tvbuff_t
*tvb
, const int offset
, int comprlen
)
52 uint8_t *uncompr
= NULL
;
53 tvbuff_t
*uncompr_tvb
;
54 BrotliDecoderState
*decoder
;
56 const size_t bufsiz
= TVB_BROTLI_BUFSIZ
;
58 const uint8_t *next_in
;
62 unsigned needs_more_output
;
65 if (tvb
== NULL
|| comprlen
<= 0) {
69 compr
= (uint8_t *)tvb_memdup(NULL
, tvb
, offset
, comprlen
);
74 decoder
= BrotliDecoderCreateInstance(
75 &brotli_g_malloc_wrapper
/*alloc_func*/,
76 &brotli_g_free_wrapper
/*free_func*/,
78 if (decoder
== NULL
) {
79 wmem_free(NULL
, compr
);
82 strmbuf
= (uint8_t *)g_malloc(bufsiz
);
84 available_in
= comprlen
;
87 needs_more_output
= 0;
89 while (available_in
> 0 || needs_more_output
) {
90 needs_more_output
= 0;
91 available_out
= bufsiz
;
94 BrotliDecoderResult result
= BrotliDecoderDecompressStream(
95 decoder
, &available_in
, &next_in
, &available_out
, &next_out
, &total_out
);
97 case BROTLI_DECODER_RESULT_SUCCESS
:
98 if (available_in
> 0) {
103 case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT
:
104 needs_more_output
= 1;
106 case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT
:
108 * It's possible that not enough frames were captured
109 * to decompress this fully, so return what we've done
113 case BROTLI_DECODER_RESULT_ERROR
:
119 * Check if decompressed size is too large.
121 if (total_out
> INT_MAX
) {
126 * BrotliDecoderDecompressStream sets available_out to the number of bytes
127 * left unused from the buffer. But we are interested in the bytes it wrote
128 * to the buffer in this pass, so we calculate pass_out.
130 size_t pass_out
= bufsiz
- available_out
;
132 uncompr
= (uint8_t *)g_realloc(uncompr
, total_out
);
133 memcpy(uncompr
+ (total_out
- pass_out
), strmbuf
, pass_out
);
137 if (uncompr
== NULL
) {
139 * This is for the case when the validly decompressed
143 uncompr
= (uint8_t *)g_strdup("");
149 uncompr_tvb
= tvb_new_real_data((uint8_t *)uncompr
, (unsigned)total_out
, (int)total_out
);
150 tvb_set_free_cb(uncompr_tvb
, g_free
);
153 wmem_free(NULL
, compr
);
154 BrotliDecoderDestroyInstance(decoder
);
160 wmem_free(NULL
, compr
);
161 BrotliDecoderDestroyInstance(decoder
);
166 tvb_uncompress_brotli(tvbuff_t
*tvb _U_
, const int offset _U_
, int comprlen _U_
)
173 tvb_child_uncompress_brotli(tvbuff_t
*parent
, tvbuff_t
*tvb
, const int offset
, int comprlen
)
175 tvbuff_t
*new_tvb
= tvb_uncompress_brotli(tvb
, offset
, comprlen
);
177 tvb_set_child_real_data_tvbuff(parent
, new_tvb
);
182 * Editor modelines - https://www.wireshark.org/tools/modelines.html
187 * indent-tabs-mode: nil
190 * vi: set shiftwidth=4 tabstop=8 expandtab:
191 * :indentSize=4:tabSize=8:noTabs=true: