File: | builds/wireshark/wireshark/epan/tvbuff_zstd.c |
Warning: | line 87, column 21 Potential leak of memory pointed to by 'uncompr' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* tvbuff_zstd.c | |||
2 | * Copyright 2022, Kevin Albertson <kevin.eric.albertson [AT] gmail.com> | |||
3 | * | |||
4 | * Wireshark - Network traffic analyzer | |||
5 | * By Gerald Combs <[email protected]> | |||
6 | * Copyright 1998 Gerald Combs | |||
7 | * | |||
8 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
9 | */ | |||
10 | ||||
11 | /* | |||
12 | * Decompress ZSTD: http://facebook.github.io/zstd/ | |||
13 | */ | |||
14 | ||||
15 | #include "config.h" | |||
16 | ||||
17 | #ifdef HAVE_ZSTD1 | |||
18 | #include <zstd.h> | |||
19 | #endif | |||
20 | ||||
21 | #include "proto.h" // DISSECTOR_ASSERT_HINT | |||
22 | #include "tvbuff.h" | |||
23 | ||||
24 | #include "tvbuff-int.h" // tvb_add_to_chain | |||
25 | ||||
26 | #define MAX_LOOP_ITERATIONS100 100 | |||
27 | ||||
28 | tvbuff_t *tvb_uncompress_zstd(tvbuff_t *tvb, const int offset, int comprlen) | |||
29 | { | |||
30 | #ifndef HAVE_ZSTD1 | |||
31 | // Cast to void to silence unused warnings. | |||
32 | (void)tvb; | |||
33 | (void)offset; | |||
34 | (void)comprlen; | |||
35 | return NULL((void*)0); | |||
36 | #else | |||
37 | ZSTD_inBuffer input = {tvb_memdup(NULL((void*)0), tvb, offset, comprlen), comprlen, 0}; | |||
38 | ZSTD_DStream *zds = ZSTD_createDStream(); | |||
39 | size_t rc = 0; | |||
40 | uint8_t *uncompr = NULL((void*)0); | |||
41 | size_t uncompr_len = 0; | |||
42 | bool_Bool ok = false0; | |||
43 | int count = 0; | |||
44 | ||||
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_ITERATIONS100) | |||
49 | { | |||
50 | rc = ZSTD_decompressStream(zds, &output, &input); | |||
51 | if (ZSTD_isError(rc)) | |||
52 | { | |||
53 | goto end; | |||
54 | } | |||
55 | ||||
56 | if (output.pos > 0) | |||
57 | { | |||
58 | if (!uncompr
| |||
59 | { | |||
60 | DISSECTOR_ASSERT (uncompr_len == 0)((void) ((uncompr_len == 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/tvbuff_zstd.c", 60, "uncompr_len == 0" )))); | |||
61 | uncompr = g_malloc(output.pos); | |||
62 | } else { | |||
63 | uncompr = g_realloc(uncompr, uncompr_len + output.pos); | |||
64 | } | |||
65 | memcpy (uncompr + uncompr_len, output.dst, output.pos); | |||
66 | uncompr_len += output.pos; | |||
67 | // Reset the output buffer. | |||
68 | output.pos = 0; | |||
69 | } | |||
70 | count++; | |||
71 | DISSECTOR_ASSERT_HINT(count < MAX_LOOP_ITERATIONS, "MAX_LOOP_ITERATIONS exceeded")((void) ((count < 100) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/tvbuff_zstd.c", 71, "count < 100", "MAX_LOOP_ITERATIONS exceeded")))); | |||
72 | } | |||
73 | if (rc > 0) | |||
74 | { | |||
75 | // There is extra data that was not decompressed. | |||
76 | goto end; | |||
77 | } | |||
78 | ||||
79 | ok = true1; | |||
80 | end: | |||
81 | g_free((void *)output.dst); | |||
82 | wmem_free(NULL((void*)0), (void *)input.src); | |||
83 | ZSTD_freeDStream(zds); | |||
84 | if (ok
| |||
85 | { | |||
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); | |||
89 | return uncompr_tvb; | |||
90 | } | |||
91 | ||||
92 | if (uncompr) | |||
93 | { | |||
94 | g_free (uncompr); | |||
95 | } | |||
96 | ||||
97 | return NULL((void*)0); | |||
98 | #endif /* HAVE_ZSTD */ | |||
99 | } | |||
100 | ||||
101 | tvbuff_t *tvb_child_uncompress_zstd(tvbuff_t *parent, tvbuff_t *tvb, const int offset, int comprlen) | |||
102 | { | |||
103 | tvbuff_t *uncompressed = tvb_uncompress_zstd(tvb, offset, comprlen); | |||
| ||||
104 | if (!uncompressed) | |||
105 | { | |||
106 | return uncompressed; | |||
107 | } | |||
108 | tvb_add_to_chain(parent, uncompressed); | |||
109 | return uncompressed; | |||
110 | } |