Bug Summary

File:builds/wireshark/wireshark/wsutil/wmem/wmem_multimap.c
Warning:line 112, column 26
Access to field 'map' results in a dereference of a null pointer (loaded from variable 'map')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name wmem_multimap.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D BUILD_WSUTIL -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wsutil_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/build/wsutil -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-10-11-100332-3663-1 -x c /builds/wireshark/wireshark/wsutil/wmem/wmem_multimap.c
1/* wmem_multimap.c
2 * Wireshark Memory Manager Hash Multimap
3 * Copyright 2021, John Thacker <johnthacker@gmail.com>
4 * Copyright 2014, Evan Huus <eapache@gmail.com>
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12#include "config.h"
13
14#include <glib.h>
15
16#include "wmem_core.h"
17#include "wmem_list.h"
18#include "wmem_map.h"
19#include "wmem_multimap.h"
20#include "wmem_tree.h"
21#include "wmem_user_cb.h"
22
23struct _wmem_multimap_t {
24
25 wmem_map_t *map;
26
27 unsigned metadata_scope_cb_id;
28 unsigned data_scope_cb_id;
29
30 wmem_allocator_t *metadata_allocator;
31 wmem_allocator_t *data_allocator;
32};
33
34wmem_multimap_t *
35wmem_multimap_new(wmem_allocator_t *allocator,
36 GHashFunc hash_func, GEqualFunc eql_func)
37{
38 wmem_multimap_t *multimap;
39
40 multimap = wmem_new(allocator, wmem_multimap_t)((wmem_multimap_t*)wmem_alloc((allocator), sizeof(wmem_multimap_t
)))
;
41
42 multimap->map = wmem_map_new(allocator, hash_func, eql_func);
43 multimap->metadata_allocator = allocator;
44 multimap->data_allocator = allocator;
45
46 return multimap;
47}
48
49static bool_Bool
50wmem_multimap_reset_cb(wmem_allocator_t *allocator _U___attribute__((unused)), wmem_cb_event_t event,
51 void *user_data)
52{
53 wmem_multimap_t *multimap = (wmem_multimap_t*)user_data;
54
55 if (event == WMEM_CB_DESTROY_EVENT) {
56 wmem_unregister_callback(multimap->metadata_allocator, multimap->metadata_scope_cb_id);
57 wmem_free(multimap->metadata_allocator, multimap);
58 }
59
60 return true1;
61}
62
63static bool_Bool
64wmem_multimap_destroy_cb(wmem_allocator_t *allocator _U___attribute__((unused)), wmem_cb_event_t event _U___attribute__((unused)),
65 void *user_data)
66{
67 wmem_multimap_t *multimap = (wmem_multimap_t*)user_data;
68
69 wmem_unregister_callback(multimap->data_allocator, multimap->data_scope_cb_id);
70
71 return false0;
72}
73
74wmem_multimap_t *
75wmem_multimap_new_autoreset(wmem_allocator_t *metadata_scope, wmem_allocator_t *data_scope,
76 GHashFunc hash_func, GEqualFunc eql_func)
77{
78 wmem_multimap_t *multimap;
79
80 multimap = wmem_new(metadata_scope, wmem_multimap_t)((wmem_multimap_t*)wmem_alloc((metadata_scope), sizeof(wmem_multimap_t
)))
;
81
82 multimap->map = wmem_map_new_autoreset(metadata_scope, data_scope, hash_func, eql_func);
83 multimap->metadata_allocator = metadata_scope;
84 multimap->data_allocator = data_scope;
85
86 multimap->metadata_scope_cb_id = wmem_register_callback(metadata_scope, wmem_multimap_destroy_cb, multimap);
87 multimap->data_scope_cb_id = wmem_register_callback(data_scope, wmem_multimap_reset_cb, multimap);
88
89 return multimap;
90}
91
92wmem_list_t*
93wmem_multimap_get_keys(wmem_allocator_t *list_allocator, const wmem_multimap_t *map)
94{
95 return wmem_map_get_keys(list_allocator, map->map);
96}
97
98static void
99count_nodes(void * key _U___attribute__((unused)), void * value, void * user_data)
100{
101 unsigned* count = (unsigned*)user_data;
102 (*count) += wmem_tree_count(value);
103}
104
105unsigned
106wmem_multimap_size(const wmem_multimap_t *map)
107{
108 unsigned count = 0;
109
110 /* Make sure we have map and a multimap */
111 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
1
Assuming 'map' is equal to NULL
112 wmem_map_foreach(map->map, count_nodes, &count);
2
Access to field 'map' results in a dereference of a null pointer (loaded from variable 'map')
113 }
114 return count;
115}
116
117unsigned
118wmem_multimap_count(const wmem_multimap_t *map, const void *key)
119{
120 wmem_tree_t *tree;
121
122 /* Make sure we have map and a multimap */
123 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
124 return 0;
125 }
126
127 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
128 return 0;
129 }
130 return wmem_tree_count(tree);
131}
132
133bool_Bool
134wmem_multimap_insert32(wmem_multimap_t *map, const void *key, uint32_t frame_num, void *value)
135{
136 wmem_tree_t *tree;
137 bool_Bool ret = true1;
138
139 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
140 tree = wmem_tree_new(map->data_allocator);
141 wmem_map_insert(map->map, key, tree);
142 ret = false0;
143 }
144 wmem_tree_insert32(tree, frame_num, value);
145
146 return ret;
147}
148
149void *
150wmem_multimap_lookup32(const wmem_multimap_t *map, const void *key, uint32_t frame_num)
151{
152 wmem_tree_t *tree;
153
154 /* Make sure we have map and a multimap */
155 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
156 return NULL((void*)0);
157 }
158
159 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
160 return NULL((void*)0);
161 }
162 return wmem_tree_lookup32(tree, frame_num);
163}
164
165void *
166wmem_multimap_lookup32_le(const wmem_multimap_t *map, const void *key, uint32_t frame_num)
167{
168 wmem_tree_t *tree;
169
170 /* Make sure we have map and a multimap */
171 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
172 return NULL((void*)0);
173 }
174
175 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
176 return NULL((void*)0);
177 }
178 return wmem_tree_lookup32_le(tree, frame_num);
179}
180
181void *
182wmem_multimap_lookup32_le_full(const wmem_multimap_t *map, const void *key, uint32_t frame_num, uint32_t *orig_frame_num)
183{
184 wmem_tree_t *tree;
185
186 /* Make sure we have map and a multimap */
187 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
188 return NULL((void*)0);
189 }
190
191 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
192 return NULL((void*)0);
193 }
194 return wmem_tree_lookup32_le_full(tree, frame_num, orig_frame_num);
195}
196
197void *
198wmem_multimap_remove32(wmem_multimap_t *map, const void *key, const uint32_t frame_num)
199{
200 wmem_tree_t *tree;
201
202 /* Make sure we have map and a multimap */
203 if (map == NULL((void*)0) || map->map == NULL((void*)0)) {
204 return NULL((void*)0);
205 }
206
207 if ((tree = wmem_map_lookup(map->map, key)) == NULL((void*)0)) {
208 return NULL((void*)0);
209 }
210 return wmem_tree_remove32(tree, frame_num);
211}
212
213/*
214 * Editor modelines - https://www.wireshark.org/tools/modelines.html
215 *
216 * Local variables:
217 * c-basic-offset: 4
218 * tab-width: 8
219 * indent-tabs-mode: nil
220 * End:
221 *
222 * vi: set shiftwidth=4 tabstop=8 expandtab:
223 * :indentSize=4:tabSize=8:noTabs=true:
224 */