2 * Copyright 2022, Kevin Albertson <kevin.eric.albertson [AT] gmail.com>
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Decompress ZSTD: http://facebook.github.io/zstd/
21 #include "proto.h" // DISSECTOR_ASSERT_HINT
24 #include "tvbuff-int.h" // tvb_add_to_chain
26 #define MAX_LOOP_ITERATIONS 100
28 tvbuff_t
*tvb_uncompress_zstd(tvbuff_t
*tvb
, const int offset
, int comprlen
)
31 // Cast to void to silence unused warnings.
37 ZSTD_inBuffer input
= {tvb_memdup(NULL
, tvb
, offset
, comprlen
), comprlen
, 0};
38 ZSTD_DStream
*zds
= ZSTD_createDStream();
40 uint8_t *uncompr
= NULL
;
41 size_t uncompr_len
= 0;
45 // ZSTD does not consume the last byte of the frame until it has flushed all of the decompressed data of the frame.
46 // Therefore, loop while there is more input.
47 ZSTD_outBuffer output
= {g_malloc(ZSTD_DStreamOutSize()), ZSTD_DStreamOutSize(), 0};
48 while (input
.pos
< input
.size
&& count
< MAX_LOOP_ITERATIONS
)
50 rc
= ZSTD_decompressStream(zds
, &output
, &input
);
60 DISSECTOR_ASSERT (uncompr_len
== 0);
61 uncompr
= g_malloc(output
.pos
);
63 uncompr
= g_realloc(uncompr
, uncompr_len
+ output
.pos
);
65 memcpy (uncompr
+ uncompr_len
, output
.dst
, output
.pos
);
66 uncompr_len
+= output
.pos
;
67 // Reset the output buffer.
71 DISSECTOR_ASSERT_HINT(count
< MAX_LOOP_ITERATIONS
, "MAX_LOOP_ITERATIONS exceeded");
75 // There is extra data that was not decompressed.
81 g_free((void *)output
.dst
);
82 wmem_free(NULL
, (void *)input
.src
);
83 ZSTD_freeDStream(zds
);
86 tvbuff_t
*uncompr_tvb
;
87 uncompr_tvb
= tvb_new_real_data (uncompr
, (unsigned)uncompr_len
, (unsigned)uncompr_len
);
88 tvb_set_free_cb (uncompr_tvb
, g_free
);
98 #endif /* HAVE_ZSTD */
101 tvbuff_t
*tvb_child_uncompress_zstd(tvbuff_t
*parent
, tvbuff_t
*tvb
, const int offset
, int comprlen
)
103 tvbuff_t
*uncompressed
= tvb_uncompress_zstd(tvb
, offset
, comprlen
);
108 tvb_add_to_chain(parent
, uncompressed
);