Bug Summary

File:builds/wireshark/wireshark/epan/wslua/wslua_tree.c
Warning:line 790, column 5
Undefined or garbage value returned to caller

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 wslua_tree.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 -isystem /usr/include/lua5.5 -isystem /builds/wireshark/wireshark/build/epan/wslua -isystem /builds/wireshark/wireshark/epan/wslua -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 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -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-24-100333-3661-1 -x c /builds/wireshark/wireshark/epan/wslua/wslua_tree.c
1/*
2 * wslua_tree.c
3 *
4 * Wireshark's interface to the Lua Programming Language
5 *
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16#include "config.h"
17
18/* WSLUA_MODULE Tree Adding Information To The Dissection Tree */
19
20#include "wslua.h"
21#include <epan/exceptions.h>
22#include <epan/show_exception.h>
23
24static int wslua_ett = -1;
25
26static GPtrArray* outstanding_TreeItem;
27
28
29/* pushing a TreeItem with a NULL item or subtree is completely valid for this function */
30TreeItem push_TreeItem(lua_State *L, proto_tree *tree, proto_item *item) {
31 TreeItem ti = g_new(struct _wslua_treeitem, 1)((struct _wslua_treeitem *) g_malloc_n ((1), sizeof (struct _wslua_treeitem
)))
;
32
33 ti->tree = tree;
34 ti->item = item;
35 ti->expired = false0;
36
37 g_ptr_array_add(outstanding_TreeItem, ti);
38
39 return *(pushTreeItem(L,ti));
40}
41
42/* creates the TreeItem but does NOT push it into Lua */
43TreeItem create_TreeItem(proto_tree* tree, proto_item* item)
44{
45 TreeItem tree_item = (TreeItem)g_malloc(sizeof(struct _wslua_treeitem));
46 tree_item->tree = tree;
47 tree_item->item = item;
48 tree_item->expired = false0;
49
50 return tree_item;
51}
52
53CLEAR_OUTSTANDING(TreeItem, expired, true)void clear_outstanding_TreeItem(void) { while (outstanding_TreeItem
->len) { TreeItem p = (TreeItem)g_ptr_array_remove_index_fast
(outstanding_TreeItem,0); if (p) { if (p->expired != 1) p->
expired = 1; else (__builtin_object_size ((p), 0) != ((size_t
) - 1)) ? g_free_sized (p, __builtin_object_size ((p), 0)) : (
g_free) (p); } } }
54
55WSLUA_CLASS_DEFINE(TreeItem,FAIL_ON_NULL_OR_EXPIRED("TreeItem"))TreeItem toTreeItem(lua_State* L, int idx) { TreeItem* v = (TreeItem
*)lua_touserdata (L, idx); if (!v) luaL_error(L, "bad argument %d (%s expected, got %s)"
, idx, "TreeItem", lua_typename(L, lua_type(L, idx))); return
v ? *v : ((void*)0); } TreeItem checkTreeItem(lua_State* L, int
idx) { TreeItem* p; luaL_checktype(L,idx,7); p = (TreeItem*)
luaL_checkudata(L, idx, "TreeItem"); if (!*p) { luaL_argerror
(L,idx,"null " "TreeItem"); } else if ((*p)->expired) { luaL_argerror
(L,idx,"expired " "TreeItem"); }; return p ? *p : ((void*)0);
} TreeItem* pushTreeItem(lua_State* L, TreeItem v) { TreeItem
* p; luaL_checkstack(L,2,"Unable to grow stack\n"); p = (TreeItem
*)lua_newuserdatauv(L,sizeof(TreeItem),1); *p = v; (lua_getfield
(L, (-(2147483647/2 + 1000)), ("TreeItem"))); lua_setmetatable
(L, -2); return p; }_Bool isTreeItem(lua_State* L,int i) { void
*p; if(!lua_isuserdata(L,i)) return 0; p = lua_touserdata(L,
i); lua_getfield(L, (-(2147483647/2 + 1000)), "TreeItem"); if
(p == ((void*)0) || !lua_getmetatable(L, i) || !lua_rawequal
(L, -1, -2)) p=((void*)0); lua_settop(L, -(2)-1); return p ? 1
: 0; } TreeItem shiftTreeItem(lua_State* L,int i) { TreeItem
* p; if(!lua_isuserdata(L,i)) return ((void*)0); p = (TreeItem
*)lua_touserdata(L, i); lua_getfield(L, (-(2147483647/2 + 1000
)), "TreeItem"); if (p == ((void*)0) || !lua_getmetatable(L, i
) || !lua_rawequal(L, -1, -2)) p=((void*)0); lua_settop(L, -(
2)-1); if (p) { (lua_rotate(L, (i), -1), lua_settop(L, -(1)-1
)); return *p; } else return ((void*)0);} typedef int dummyTreeItem
;
56/* <<lua_class_TreeItem,`TreeItem`>>s represent information in the https://www.wireshark.org/docs/wsug_html_chunked/ChUsePacketDetailsPaneSection.html[packet details] pane of Wireshark, and the packet details view of TShark.
57 A <<lua_class_TreeItem,`TreeItem`>> represents a node in the tree, which might also be a subtree and have a list of children.
58 The children of a subtree have zero or more siblings which are other children of the same <<lua_class_TreeItem,`TreeItem`>> subtree.
59
60 During dissection, heuristic-dissection, and post-dissection, a root <<lua_class_TreeItem,`TreeItem`>> is passed to dissectors as the third argument of the function
61 callback (e.g., `myproto.dissector(tvbuf,pktinfo,root)`).
62
63 In some cases the tree is not truly added to, in order to improve performance.
64 For example for packets not currently displayed/selected in Wireshark's visible
65 window pane, or if TShark isn't invoked with the `-V` switch. However the
66 "add" type <<lua_class_TreeItem,`TreeItem`>> functions can still be called, and still return <<lua_class_TreeItem,`TreeItem`>>
67 objects - but the info isn't really added to the tree. Therefore you do not
68 typically need to worry about whether there's a real tree or not. If, for some
69 reason, you need to know it, you can use the <<lua_class_attrib_treeitem_visible,`TreeItem.visible`>> attribute getter
70 to retrieve the state.
71 */
72
73/* the following is used by TreeItem_add_packet_field() - this can THROW errors */
74static proto_item *
75try_add_packet_field(lua_State *L, TreeItem tree_item, TvbRange tvbr, const int hfid,
76 const ftenum_t type, const unsigned encoding, int *ret_err)
77{
78 int err = 0;
79 proto_item *volatile item = NULL((void*)0);
80 unsigned endoff = 0;
81
82 switch(type) {
83 /* these all generate ByteArrays */
84 case FT_BYTES:
85 case FT_UINT_BYTES:
86 case FT_OID:
87 case FT_REL_OID:
88 case FT_SYSTEM_ID:
89 {
90 /* GByteArray and its data will be g_free'd by Lua */
91 GByteArray *gba = g_byte_array_new();
92 item = proto_tree_add_bytes_item(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
93 tvbr->offset, tvbr->len, encoding,
94 gba, &endoff, &err);
95 if (err == 0) {
96 pushByteArray(L, gba);
97 lua_pushinteger(L, endoff);
98 }
99 }
100 break;
101
102 case FT_ABSOLUTE_TIME:
103 case FT_RELATIVE_TIME:
104 {
105 /* nstime_t will be g_free'd by Lua */
106 nstime_t *nstime = g_new0(nstime_t, 1)((nstime_t *) g_malloc0_n ((1), sizeof (nstime_t)));
107 item = proto_tree_add_time_item(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
108 tvbr->offset, tvbr->len, encoding,
109 nstime, &endoff, &err);
110 if (err == 0) {
111 pushNSTime(L,nstime);
112 lua_pushinteger(L, endoff);
113 }
114 }
115 break;
116
117 case FT_INT8:
118 case FT_INT16:
119 case FT_INT24:
120 case FT_INT32:
121 {
122 int32_t ret;
123 item = proto_tree_add_item_ret_int(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
124 tvbr->offset, tvbr->len, encoding,
125 &ret);
126 lua_pushinteger(L, (lua_Integer)ret);
127 lua_pushinteger(L, tvbr->offset + tvbr->len);
128 }
129 break;
130
131 case FT_INT40:
132 case FT_INT48:
133 case FT_INT56:
134 case FT_INT64:
135 {
136 int64_t ret;
137 item = proto_tree_add_item_ret_int64(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
138 tvbr->offset, tvbr->len, encoding,
139 &ret);
140 pushInt64(L, ret);
141 lua_pushinteger(L, tvbr->offset + tvbr->len);
142 }
143 break;
144
145 case FT_CHAR:
146 case FT_UINT8:
147 case FT_UINT16:
148 case FT_UINT24:
149 case FT_UINT32:
150 {
151 uint32_t ret;
152 item = proto_tree_add_item_ret_uint(tree_item-> tree, hfid, tvbr->tvb.ws_tvb,
153 tvbr->offset, tvbr->len, encoding,
154 &ret);
155 lua_pushinteger(L, (lua_Integer)ret);
156 lua_pushinteger(L, tvbr->offset + tvbr->len);
157 }
158 break;
159
160 case FT_UINT40:
161 case FT_UINT48:
162 case FT_UINT56:
163 case FT_UINT64:
164 {
165 uint64_t ret;
166 item = proto_tree_add_item_ret_uint64(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
167 tvbr->offset, tvbr->len, encoding,
168 &ret);
169 pushUInt64(L, ret);
170 lua_pushinteger(L, tvbr->offset + tvbr->len);
171 }
172 break;
173
174 case FT_BOOLEAN:
175 {
176 bool_Bool ret;
177 item = proto_tree_add_item_ret_boolean(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
178 tvbr->offset, tvbr->len, encoding,
179 &ret);
180 lua_pushboolean(L, ret);
181 lua_pushinteger(L, tvbr->offset + tvbr->len);
182 }
183 break;
184
185 case FT_STRING:
186 case FT_STRINGZ:
187 case FT_STRINGZPAD:
188 case FT_STRINGZTRUNC:
189 case FT_UINT_STRING:
190 {
191 const uint8_t *ret;
192 unsigned len;
193 item = proto_tree_add_item_ret_string_and_length(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
194 tvbr->offset, tvbr->len, encoding,
195 NULL((void*)0), &ret, &len);
196 lua_pushstring(L, (const char*)ret);
197 lua_pushinteger(L, tvbr->offset + len);
198 wmem_free(NULL((void*)0), (void*)ret);
199 }
200 break;
201
202 case FT_FLOAT:
203 {
204 float ret;
205 item = proto_tree_add_item_ret_float(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
206 tvbr->offset, tvbr->len, encoding,
207 &ret);
208 lua_pushnumber(L, (lua_Number)ret);
209 lua_pushinteger(L, tvbr->offset + tvbr->len);
210 }
211 break;
212
213 case FT_DOUBLE:
214 {
215 double ret;
216 item = proto_tree_add_item_ret_double(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
217 tvbr->offset, tvbr->len, encoding,
218 &ret);
219 lua_pushnumber(L, (lua_Number)ret);
220 lua_pushinteger(L, tvbr->offset + tvbr->len);
221 }
222 break;
223
224 case FT_IPv4:
225 {
226 Address addr = g_new(address,1)((address *) g_malloc_n ((1), sizeof (address)));
227 ws_in4_addr ret;
228 item = proto_tree_add_item_ret_ipv4(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
229 tvbr->offset, tvbr->len, encoding,
230 &ret);
231 alloc_address_wmem(NULL((void*)0), addr, AT_IPv4, sizeof(ret), &ret);
232 pushAddress(L, addr);
233 lua_pushinteger(L, tvbr->offset + tvbr->len);
234 }
235 break;
236
237 case FT_IPv6:
238 {
239 Address addr = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
240 ws_in6_addr ret;
241 item = proto_tree_add_item_ret_ipv6(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
242 tvbr->offset, tvbr->len, encoding,
243 &ret);
244 alloc_address_wmem(NULL((void*)0), addr, AT_IPv6, sizeof(ret), &ret);
245 pushAddress(L, addr);
246 lua_pushinteger(L, tvbr->offset + tvbr->len);
247 }
248 break;
249
250 case FT_ETHER:
251 {
252 Address addr = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
253 uint8_t bytes[FT_ETHER_LEN6];
254
255 item = proto_tree_add_item_ret_ether(tree_item->tree, hfid, tvbr->tvb.ws_tvb,
256 tvbr->offset, tvbr->len, encoding,
257 bytes);
258 alloc_address_wmem(NULL((void*)0), addr, AT_ETHER, sizeof(bytes), bytes);
259 pushAddress(L, addr);
260 lua_pushinteger(L, tvbr->offset + tvbr->len);
261 }
262 break;
263
264 default:
265 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len, encoding);
266 lua_pushnil(L);
267 lua_pushnil(L);
268 break;
269 }
270
271 if (ret_err) *ret_err = err;
272
273 return item;
274}
275
276WSLUA_METHODstatic int TreeItem_add_packet_field(lua_State *L) {
277 /*
278 Adds a new child tree for the given <<lua_class_ProtoField,`ProtoField`>> object to this tree item,
279 returning the new child <<lua_class_TreeItem,`TreeItem`>>.
280
281 Unlike `TreeItem:add()` and `TreeItem:add_le()`, the <<lua_class_ProtoField,`ProtoField`>> argument
282 is not optional, and cannot be a `Proto` object. Instead, this function always
283 uses the <<lua_class_ProtoField,`ProtoField`>> to determine the type of field to extract from the
284 passed-in `TvbRange`, highlighting the relevant bytes in the Packet Bytes pane
285 of the GUI (if there is a GUI), etc. If no <<lua_class_TvbRange,`TvbRange`>>is given, no bytes are
286 highlighted and the field's value cannot be determined; the <<lua_class_ProtoField,`ProtoField`>> must
287 have been defined/created not to have a length in such a case, or an error will
288 occur. For backwards-compatibility reasons the `encoding` argument, however,
289 must still be given.
290
291 Unlike `TreeItem:add()` and `TreeItem:add_le()`, this function performs both
292 big-endian and little-endian decoding, by setting the `encoding` argument to
293 be `ENC_BIG_ENDIAN` or `ENC_LITTLE_ENDIAN`.
294
295 The signature of this function:
296
297 [source,lua]
298 ----
299 tree_item:add_packet_field(proto_field [,tvbrange], encoding, ...)
300 ----
301
302 This function returns more than just the new child <<lua_class_TreeItem,`TreeItem`>>.
303 The child is the first return value, so that function chaining will still work; but it
304 also returns more information. The second return is the value of the extracted field
305 (i.e., a number, `UInt64`, `Address`, etc.). The third return is is the offset where
306 data should be read next. This is useful when the length of the field is not known in
307 advance. The additional return values may be null if the field type is not well supported
308 in the Lua API.
309
310 This function can extract a <<lua_class_ProtoField,`ProtoField`>> of type `ftypes.BYTES`
311 or `ftypes.ABSOLUTE_TIME` from a string in the `TvbRange` in ASCII-based and similar
312 encodings. For example, a `ProtoField` of `ftypes.BYTES` can be extracted from a `TvbRange`
313 containing the ASCII string "a1b2c3d4e5f6", and it will correctly decode the ASCII both in the
314 tree as well as for the second return value, which will be a <<lua_class_ByteArray,`ByteArray`>>.
315 To do so, you must set the `encoding` argument of this function to the appropriate string `ENC_*`
316 value, bitwise-or'd (or added) with the `ENC_STR_HEX` value and one or more `ENC_SEP_XXX` values
317 indicating which encodings are allowed. For `ftypes.ABSOLUTE_TIME`, one of the `ENC_ISO_8601_*`
318 encodings or `ENC_IMF_DATE_TIME` must be used, and the second return value is a <<lua_class_NSTime,`NSTime`>>.
319 Only single-byte ASCII digit string encodings such as `ENC_ASCII` and `ENC_UTF_8` can be used for this.
320
321 For example, assuming the <<lua_class_Tvb,`Tvb`>> named "`tvb`" contains the string "abcdef"
322 (61 62 63 64 65 66 in hex):
323
324 [source,lua]
325 ----
326 -- this is done earlier in the script
327 local myfield = ProtoField.new("Transaction ID", "myproto.trans_id", ftypes.BYTES)
328 myproto.fields = { myfield }
329
330 -- this is done inside a dissector, post-dissector, or heuristic function
331 -- child will be the created child tree, and value will be the ByteArray "abcdef" or nil on failure
332 local child, value = tree:add_packet_field(myfield, tvb:range(0,6), ENC_UTF_8 + ENC_STR_HEX + ENC_SEP_NONE)
333 ----
334
335 */
336#define WSLUA_ARG_TreeItem_add_packet_field_PROTOFIELD2 2 /* The ProtoField field object to add to the tree. */
337#define WSLUA_OPTARG_TreeItem_add_packet_field_TVBRANGE3 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
338#define WSLUA_ARG_TreeItem_add_packet_field_ENCODING4 4 /* The field's encoding in the `TvbRange`. */
339#define WSLUA_OPTARG_TreeItem_add_packet_field_LABEL5 5 /* One or more strings to append to the created <<lua_class_TreeItem,`TreeItem`>>. */
340 volatile TvbRange tvbr;
341 ProtoField field;
342 int hfid;
343 volatile int ett;
344 ftenum_t type;
345 TreeItem tree_item = shiftTreeItem(L,1);
346 unsigned encoding;
347 proto_item* item = NULL((void*)0);
348 volatile int nargs;
349 volatile int err = 0;
350 const char *volatile error = NULL((void*)0);
351
352 if (!tree_item) {
353 return luaL_error(L,"not a TreeItem!");
354 }
355 if (tree_item->expired) {
356 luaL_error(L,"expired TreeItem");
357 return 0;
358 }
359
360 if (! ( field = shiftProtoField(L,1) ) ) {
361 luaL_error(L,"TreeField:add_packet_field not passed a ProtoField");
362 return 0;
363 }
364 if (field->hfid == -2) {
365 luaL_error(L, "ProtoField %s unregistered (not added to a Proto.fields attribute)", field->abbrev);
366 }
367 hfid = field->hfid;
368 type = field->type;
369 ett = field->ett;
370
371 tvbr = shiftTvbRange(L,1);
372 if (tvbr && tvbr->tvb.expired) {
373 luaL_error(L,"expired tvb");
374 return 0;
375 }
376 if (!tvbr) {
377 /* No TvbRange specified */
378 tvbr = wmem_new0(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc0((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
379 tvbr->tvb.ws_tvb = lua_tvb;
380 tvbr->offset = 0;
381 tvbr->len = 0;
382 }
383
384 encoding = wslua_checkuint(L,1)(unsigned) ( luaL_checkinteger(L,1) );
385 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
386
387 /* get the number of additional args before we add more to the stack */
388 nargs = lua_gettop(L);
389
390 /* XXX: why is this being done? If the length was -1, FT_STRINGZ figures out
391 * the right length in tvb_get_stringz_enc(); if it was 0, it should remain zero;
392 * if it was greater than zero, then it's the length the caller wanted.
393 */
394 if (type == FT_STRINGZ) {
395 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
396
397 case ENC_UTF_160x00000004:
398 case ENC_UCS_20x00000006:
399 tvbr->len = tvb_unicode_strsize (tvbr->tvb.ws_tvb, tvbr->offset);
400 break;
401
402 default:
403 if (!tvb_find_uint8_remaining(tvbr->tvb.ws_tvb, tvbr->offset, 0, NULL((void*)0))) {
404 luaL_error(L,"out of bounds");
405 return 0;
406 }
407 tvbr->len = tvb_strsize (tvbr->tvb.ws_tvb, tvbr->offset);
408 break;
409 }
410 }
411
412 TRY{ except_t *volatile exc; volatile int except_state = 0; static
const except_id_t catch_spec[] = { { 1, 0 } }; { struct except_stacknode
except_sn; struct except_catch except_ch; except_setup_try(&
except_sn, &except_ch, catch_spec, 1); if (_setjmp (except_ch
.except_jmp)) *(&exc) = &except_ch.except_obj; else *
(&exc) = 0; if(except_state & 1) except_state |= 2; except_state
&= ~1; if (except_state == 0 && exc == 0)
{
413 int errx = 0;
414 item = try_add_packet_field(L, tree_item, tvbr, hfid, type, encoding, &errx);
415 err = errx;
416 } CATCH_ALLif (except_state == 0 && exc != 0 && (except_state
|=1))
{
417 show_exception(tvbr->tvb.ws_tvb, lua_pinfo, tree_item->tree, EXCEPT_CODE((exc)->except_id.except_code), GET_MESSAGE((exc)->except_message));
418 error = "Lua programming error";
419 } ENDTRYif(!(except_state&1) && exc != 0) except_rethrow(
exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}
;
420
421 if (error) { WSLUA_ERROR(TreeItem_add_packet_field,error){ luaL_error(L, "%s%s", "TreeItem_add_packet_field" ": ", error
); }
; }
422
423 if (err != 0) {
424 lua_pushnil(L);
425 lua_pushnil(L);
426 }
427
428 while(nargs) {
429 const char* s;
430 s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
431 if (s) proto_item_append_text(item, " %s", s);
432 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
433 nargs--;
434 }
435
436 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
437
438 /* move the tree object before the field value */
439 lua_insert(L, 1)lua_rotate(L, (1), 1);
440
441 WSLUA_RETURN(3)return (3); /* The new child <<lua_class_TreeItem,`TreeItem`>>, the field's extracted value or nil, and offset or nil. */
442}
443
444/* The following is used by TreeItem_add() and TreeItem_add_le() and can THROW.
445 * It should be called inside a TRY (e.g. WRAP_NON_LUA_EXCEPTIONS) block and
446 * THROW_LUA_ERROR should be used insteadof lua[L]_error.
447 */
448static int TreeItem_add_item_any(lua_State *L, bool_Bool little_endian) {
449 TvbRange tvbr;
450 Proto proto;
451 ProtoField field;
452 int hfid = -1;
453 int ett = -1;
454 ftenum_t type = FT_NONE;
455 TreeItem tree_item = shiftTreeItem(L,1);
456 proto_item* item = NULL((void*)0);
457
458 if (!tree_item) {
459 THROW_LUA_ERROR("not a TreeItem!")except_throwf(1, (6), "not a TreeItem!");
460 }
461 if (tree_item->expired) {
462 THROW_LUA_ERROR("expired TreeItem")except_throwf(1, (6), "expired TreeItem");
463 return 0;
464 }
465
466 if (! ( field = shiftProtoField(L,1) ) ) {
467 if (( proto = shiftProto(L,1) )) {
468 hfid = proto->hfid;
469 type = FT_PROTOCOL;
470 ett = proto->ett;
471 } else if (lua_isnil(L, 1)(lua_type(L, (1)) == 0)) {
472 THROW_LUA_ERROR("first argument to TreeItem:add is nil!")except_throwf(1, (6), "first argument to TreeItem:add is nil!"
)
;
473 }
474 } else {
475 hfid = field->hfid;
476 type = field->type;
477 ett = field->ett;
478 }
479
480 tvbr = shiftTvbRange(L,1);
481 if (tvbr && tvbr->tvb.expired) {
482 THROW_LUA_ERROR("expired tvb")except_throwf(1, (6), "expired tvb");
483 return 0;
484 }
485
486 if (!tvbr) {
487 tvbr = wmem_new0(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc0((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
488 tvbr->tvb.ws_tvb = lua_tvb;
489 tvbr->offset = 0;
490 tvbr->len = 0;
491 }
492
493 if (hfid > 0 ) {
494 /* hfid is > 0 when the first arg was a ProtoField or Proto */
495
496 if (type == FT_STRINGZ) {
497 if (!tvb_find_uint8_remaining(tvbr->tvb.ws_tvb, tvbr->offset, 0, NULL((void*)0))) {
498 THROW_LUA_ERROR("out of bounds")except_throwf(1, (6), "out of bounds");
499 return 0;
500 }
501 tvbr->len = tvb_strsize (tvbr->tvb.ws_tvb, tvbr->offset);
502 }
503
504 if (lua_gettop(L)) {
505 /* if we got here, the (L,1) index is the value to add, instead of decoding from the Tvb */
506
507 /* It's invalid for it to be nil (which has been documented for
508 * a long time). Make sure we throw our error instead of an
509 * internal Lua error (due to nested setjmp/longjmp).
510 */
511 if (lua_isnil(L, 1)(lua_type(L, (1)) == 0)) {
512 THROW_LUA_ERROR("TreeItem:add value argument is nil!")except_throwf(1, (6), "TreeItem:add value argument is nil!");
513 }
514
515 switch(type) {
516 case FT_PROTOCOL:
517 item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,ENC_NA0x00000000);
518 lua_pushinteger(L,0);
519 lua_insert(L,1)lua_rotate(L, (1), 1);
520 break;
521 case FT_BOOLEAN:
522 {
523 uint64_t val;
524 switch(lua_type(L, 1)) {
525
526 case LUA_TUSERDATA7:
527 val = checkUInt64(L, 1);
528 break;
529
530 default:
531 /* this needs to use checkinteger so that it can accept a Lua boolean and coerce it to an int */
532 val = (uint64_t) (wslua_tointeger(L,1));
533 }
534 item = proto_tree_add_boolean(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,val);
535 }
536 break;
537 case FT_CHAR:
538 case FT_UINT8:
539 case FT_UINT16:
540 case FT_UINT24:
541 case FT_UINT32:
542 case FT_FRAMENUM:
543 if (!lua_isnumber(L,1)) {
544 THROW_LUA_ERROR("Expected number for unsigned integer field")except_throwf(1, (6), "Expected number for unsigned integer field"
)
;
545 return 0;
546 }
547 item = proto_tree_add_uint(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,wslua_checkuint32(L,1)(uint32_t) ( luaL_checkinteger(L,1) ));
548 break;
549 case FT_INT8:
550 case FT_INT16:
551 case FT_INT24:
552 case FT_INT32:
553 if (!lua_isnumber(L,1)) {
554 THROW_LUA_ERROR("Expected number for integer field")except_throwf(1, (6), "Expected number for integer field");
555 return 0;
556 }
557 item = proto_tree_add_int(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,wslua_checkint32(L,1)(int32_t) ( luaL_checkinteger(L,1) ));
558 break;
559 case FT_FLOAT:
560 if (!lua_isnumber(L,1)) {
561 THROW_LUA_ERROR("Expected number for FT_FLOAT field")except_throwf(1, (6), "Expected number for FT_FLOAT field");
562 return 0;
563 }
564 item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
565 break;
566 case FT_DOUBLE:
567 if (!lua_isnumber(L,1)) {
568 THROW_LUA_ERROR("Expected number for FT_DOUBLE field")except_throwf(1, (6), "Expected number for FT_DOUBLE field");
569 return 0;
570 }
571 item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
572 break;
573 case FT_ABSOLUTE_TIME:
574 case FT_RELATIVE_TIME:
575 if (!isNSTime(L,1)) {
576 THROW_LUA_ERROR("Expected NSTime for %s field", (type==FT_ABSOLUTE_TIME ? "FT_ABSOLUTE_TIME" : "FT_RELATIVE_TIME"))except_throwf(1, (6), "Expected NSTime for %s field", (type==
FT_ABSOLUTE_TIME ? "FT_ABSOLUTE_TIME" : "FT_RELATIVE_TIME"))
;
577 return 0;
578 }
579 item = proto_tree_add_time(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,checkNSTime(L,1));
580 break;
581 case FT_STRING:
582 case FT_STRINGZ:
583 {
584 const char *value = lua_tostring(L, 1)lua_tolstring(L, (1), ((void*)0));
585 if (value == NULL((void*)0)) {
586 THROW_LUA_ERROR("Expected string for %s field", (type==FT_STRING ? "FT_STRING" : "FT_STRINGZ") )except_throwf(1, (6), "Expected string for %s field", (type==
FT_STRING ? "FT_STRING" : "FT_STRINGZ"))
;
587 return 0;
588 }
589 item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,value);
590 }
591 break;
592 case FT_BYTES:
593 {
594 const char *value = lua_tostring(L, 1)lua_tolstring(L, (1), ((void*)0));
595 if (value == NULL((void*)0)) {
596 THROW_LUA_ERROR("Expected bytes for FT_BYTES field")except_throwf(1, (6), "Expected bytes for FT_BYTES field");
597 return 0;
598 }
599 item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len, (const uint8_t*)value);
600 }
601 break;
602 case FT_UINT64:
603 if (!isUInt64(L,1)) {
604 THROW_LUA_ERROR("Expected UInt64 for FT_UINT64 field")except_throwf(1, (6), "Expected UInt64 for FT_UINT64 field");
605 return 0;
606 }
607 item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,checkUInt64(L,1));
608 break;
609 case FT_INT64:
610 if (!isInt64(L,1)) {
611 THROW_LUA_ERROR("Expected Int64 for FT_INT64 field")except_throwf(1, (6), "Expected Int64 for FT_INT64 field");
612 return 0;
613 }
614 item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,checkInt64(L,1));
615 break;
616 case FT_IPv4:
617 {
618 Address addr = isAddress(L,1) ? checkAddress(L,1) : NULL((void*)0);
619 uint32_t addr_value;
620
621 if (addr == NULL((void*)0) || addr->type != AT_IPv4) {
622 THROW_LUA_ERROR("Expected IPv4 address for FT_IPv4 field")except_throwf(1, (6), "Expected IPv4 address for FT_IPv4 field"
)
;
623 return 0;
624 }
625
626 /*
627 * The address is not guaranteed to be aligned on a
628 * 32-bit boundary, so we can't safely dereference
629 * the pointer as if it were so aligned.
630 */
631 memcpy(&addr_value, addr->data, sizeof addr_value);
632 item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb.ws_tvb,tvbr->offset,tvbr->len,addr_value);
633 }
634 break;
635 case FT_IPv6:
636 {
637 Address addr = isAddress(L,1) ? checkAddress(L,1) : NULL((void*)0);
638 if (addr == NULL((void*)0) || addr->type != AT_IPv6) {
639 THROW_LUA_ERROR("Expected IPv6 address for FT_IPv6 field")except_throwf(1, (6), "Expected IPv6 address for FT_IPv6 field"
)
;
640 return 0;
641 }
642
643 item = proto_tree_add_ipv6(tree_item->tree, hfid, tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len, (const ws_in6_addr *)addr->data);
644 }
645 break;
646 case FT_ETHER:
647 {
648 Address addr = isAddress(L,1) ? checkAddress(L,1) : NULL((void*)0);
649 if (addr == NULL((void*)0) || addr->type != AT_ETHER) {
650 THROW_LUA_ERROR("Expected MAC address for FT_ETHER field")except_throwf(1, (6), "Expected MAC address for FT_ETHER field"
)
;
651 return 0;
652 }
653
654 item = proto_tree_add_ether(tree_item->tree, hfid, tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len, (const uint8_t *)addr->data);
655 }
656 break;
657 case FT_UINT_BYTES:
658 case FT_IPXNET:
659 case FT_GUID:
660 case FT_OID:
661 case FT_REL_OID:
662 case FT_SYSTEM_ID:
663 case FT_VINES:
664 case FT_FCWWN:
665 default:
666 THROW_LUA_ERROR("%s not yet supported", ftype_name(type))except_throwf(1, (6), "%s not yet supported", ftype_name(type
))
;
667 return 0;
668 }
669
670 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
671
672 } else {
673 if (type == FT_FRAMENUM) {
674 THROW_LUA_ERROR("ProtoField FRAMENUM cannot fetch value from Tvb")except_throwf(1, (6), "ProtoField FRAMENUM cannot fetch value from Tvb"
)
;
675 return 0;
676 }
677 /* the Lua stack is empty - no value was given - so decode the value from the tvb */
678 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len, little_endian ? ENC_LITTLE_ENDIAN0x80000000 : ENC_BIG_ENDIAN0x00000000);
679 }
680
681 if ( lua_gettop(L) ) {
682 /* if there was a value, it was removed earlier, so what's left is the display string to set */
683 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
684 if (s) proto_item_set_text(item,"%s",s);
685 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
686 }
687
688 } else {
689 /* no ProtoField or Proto was given - we're adding a text-only field,
690 * any remaining parameters are parts of the text label. */
691 if (lua_gettop(L)) {
692 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
693 const int hf = get_hf_wslua_text();
694 if (hf > -1) {
695 /* use proto_tree_add_none_format() instead? */
696 item = proto_tree_add_item(tree_item->tree, hf, tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len, ENC_NA0x00000000);
697 proto_item_set_text(item, "%s", s);
698 } else {
699 THROW_LUA_ERROR("Internal error: hf_wslua_text not registered")except_throwf(1, (6), "Internal error: hf_wslua_text not registered"
)
;
700 }
701 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
702 } else {
703 THROW_LUA_ERROR("Tree item ProtoField/Protocol handle is invalid (ProtoField/Proto not registered?)")except_throwf(1, (6), "Tree item ProtoField/Protocol handle is invalid (ProtoField/Proto not registered?)"
)
;
704 }
705 }
706
707 while(lua_gettop(L)) {
708 /* keep appending more text */
709 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
710 if (s) proto_item_append_text(item, " %s", s);
711 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
712 }
713
714 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
715
716 return 1;
717}
718
719
720WSLUA_METHODstatic int TreeItem_add(lua_State *L) {
721 /*
722 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
723
724 If the <<lua_class_ProtoField,`ProtoField`>> represents a numeric value (int, uint or float), then it's treated as a Big Endian (network order) value.
725
726 This function has a complicated form: 'treeitem:add([protofield,] [tvbrange,] [[value], label]])', such that if the first
727 argument is a <<lua_class_ProtoField,`ProtoField`>> or a <<lua_class_Proto,`Proto`>>, the second argument is a <<lua_class_TvbRange,`TvbRange`>>, and a third argument is given, it's a value;
728 but if the second argument is a non-<<lua_class_TvbRange,`TvbRange`>>, then it's the value (as opposed to filling that argument with 'nil',
729 which is invalid for this function). If the first argument is a non-<<lua_class_ProtoField,`ProtoField`>> and a non-<<lua_class_Proto,`Proto`>> then this argument can
730 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
731
732 [discrete]
733 ====== Example
734
735 [source,lua]
736 ----
737 local proto_foo = Proto("foo", "Foo Protocol")
738 proto_foo.fields.bytes = ProtoField.bytes("foo.bytes", "Byte array")
739 proto_foo.fields.u16 = ProtoField.uint16("foo.u16", "Unsigned short", base.HEX)
740
741 function proto_foo.dissector(buf, pinfo, tree)
742 -- ignore packets less than 4 bytes long
743 if buf:len() < 4 then return end
744
745 -- ##############################################
746 -- # Assume buf(0,4) == {0x00, 0x01, 0x00, 0x02}
747 -- ##############################################
748
749 local t = tree:add( proto_foo, buf() )
750
751 -- Adds a byte array that shows as: "Byte array: 00010002"
752 t:add( proto_foo.fields.bytes, buf(0,4) )
753
754 -- Adds a byte array that shows as "Byte array: 313233"
755 -- (the ASCII char code of each character in "123")
756 t:add( proto_foo.fields.bytes, buf(0,4), "123" )
757
758 -- Adds a tree item that shows as: "Unsigned short: 0x0001"
759 t:add( proto_foo.fields.u16, buf(0,2) )
760
761 -- Adds a tree item that shows as: "Unsigned short: 0x0064"
762 t:add( proto_foo.fields.u16, buf(0,2), 100 )
763
764 -- Adds a tree item that shows as: "Unsigned short: 0x0064 ( big endian )"
765 t:add( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "big", 999, nil, "endian", nil, ")" )
766
767 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x0100"
768 t:add_le( proto_foo.fields.u16, buf(0,2) )
769
770 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400"
771 t:add_le( proto_foo.fields.u16, buf(0,2), 100 )
772
773 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400 ( little endian )"
774 t:add_le( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "little", 999, nil, "endian", nil, ")" )
775 end
776
777 udp_table = DissectorTable.get("udp.port")
778 udp_table:add(7777, proto_foo)
779 ----
780 */
781#define WSLUA_OPTARG_TreeItem_add_PROTOFIELD2 2 /* The <<lua_class_ProtoField,`ProtoField`>> field or <<lua_class_Proto,`Proto`>> protocol object to add to the tree. */
782#define WSLUA_OPTARG_TreeItem_add_TVBRANGE3 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
783#define WSLUA_OPTARG_TreeItem_add_VALUE4 4 /* The field's value, instead of the ProtoField/Proto one. */
784#define WSLUA_OPTARG_TreeItem_add_LABEL5 5 /* One or more strings to use for the tree item label, instead of the ProtoField/Proto one. */
785
786 volatile int ret;
1
'ret' declared without an initial value
787 WRAP_NON_LUA_EXCEPTIONS({ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,0)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
2
Assuming the condition is true
3
Taking true branch
4
Taking false branch
5
Taking false branch
6
Assuming field 'except_code' is equal to 1
7
Taking true branch
8
Taking false branch
788 ret = TreeItem_add_item_any(L,false);{ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,0)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
789 ){ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,0)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
790 WSLUA_RETURN(ret)return (ret); /* The new child TreeItem. */
9
Undefined or garbage value returned to caller
791}
792
793WSLUA_METHODstatic int TreeItem_add_le(lua_State *L) {
794 /*
795 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
796
797 If the <<lua_class_ProtoField,`ProtoField`>> represents a numeric value (int, uint or float), then it's treated as a Little Endian value.
798
799 This function has a complicated form: 'treeitem:add_le([protofield,] [tvbrange,] [[value], label]])', such that if the first
800 argument is a <<lua_class_ProtoField,`ProtoField`>> or a <<lua_class_Proto,`Proto`>>, the second argument is a <<lua_class_TvbRange,`TvbRange`>>, and a third argument is given, it's a value;
801 but if the second argument is a non-<<lua_class_TvbRange,`TvbRange`>>, then it's the value (as opposed to filling that argument with 'nil',
802 which is invalid for this function). If the first argument is a non-<<lua_class_ProtoField,`ProtoField`>> and a non-<<lua_class_Proto,`Proto`>> then this argument can
803 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
804 */
805#define WSLUA_OPTARG_TreeItem_add_le_PROTOFIELD2 2 /* The ProtoField field or Proto protocol object to add to the tree. */
806#define WSLUA_OPTARG_TreeItem_add_le_TVBRANGE3 3 /* The TvbRange of bytes in the packet this tree item covers/represents. */
807#define WSLUA_OPTARG_TreeItem_add_le_VALUE4 4 /* The field's value, instead of the ProtoField/Proto one. */
808#define WSLUA_OPTARG_TreeItem_add_le_LABEL5 5 /* One or more strings to use for the tree item label, instead of the ProtoField/Proto one. */
809 volatile int ret;
810 WRAP_NON_LUA_EXCEPTIONS({ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,1)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
811 ret = TreeItem_add_item_any(L,true);{ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,1)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
812 ){ volatile _Bool has_error = 0; { except_t *volatile exc; volatile
int except_state = 0; static const except_id_t catch_spec[] =
{ { 1, 0 } }; { struct except_stacknode except_sn; struct except_catch
except_ch; except_setup_try(&except_sn, &except_ch, catch_spec
, 1); if (_setjmp (except_ch.except_jmp)) *(&exc) = &
except_ch.except_obj; else *(&exc) = 0; if(except_state &
1) except_state |= 2; except_state &= ~1; if (except_state
== 0 && exc == 0) { ret = TreeItem_add_item_any(L,1)
; } if (except_state == 0 && exc != 0 && (exc
->except_id.except_code == (1) || exc->except_id.except_code
== (4) || exc->except_id.except_code == (7)) && (
except_state|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree
->tree, ((exc)->except_id.except_code), ((exc)->except_message
)); } if (except_state == 0 && exc != 0 && (except_state
|=1)) { show_exception(lua_tvb, lua_pinfo, lua_tree->tree,
((exc)->except_id.except_code), ((exc)->except_message
)); lua_pushfstring(L, "%s: %s", __func__, ((exc)->except_message
) ? ((exc)->except_message) : "Malformed packet"); has_error
= 1; } if(!(except_state&1) && exc != 0) except_rethrow
(exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}; if (has_error) { lua_error(L); } }
813 WSLUA_RETURN(ret)return (ret); /* The new child TreeItem. */
814}
815
816/* WSLUA_ATTRIBUTE TreeItem_text RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s display string (string).
817
818 For the getter, if the TreeItem has no display string, then nil is returned.
819 */
820static int TreeItem_get_text(lua_State* L) {
821 TreeItem ti = checkTreeItem(L,1);
822 char label_str[ITEM_LABEL_LENGTH240+1];
823 char *label_ptr;
824
825 if (ti->item && PITEM_FINFO(ti->item)((ti->item)->finfo)) {
826 field_info *fi = PITEM_FINFO(ti->item)((ti->item)->finfo);
827
828 if (!fi->rep) {
829 label_ptr = label_str;
830 proto_item_fill_label(fi, label_str, NULL((void*)0));
831 } else
832 label_ptr = fi->rep->representation;
833
834 if (label_ptr) {
835 lua_pushstring(L, label_ptr);
836 } else {
837 lua_pushnil(L);
838 }
839 } else {
840 lua_pushnil(L);
841 }
842
843 return 1;
844}
845
846/* the following is used as both a method and attribute */
847WSLUA_METHODstatic int TreeItem_set_text(lua_State *L) {
848 /* Sets the text of the label.
849
850 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
851 */
852#define WSLUA_ARG_TreeItem_set_text_TEXT2 2 /* The text to be used. */
853 TreeItem ti = checkTreeItem(L,1);
854 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_set_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
855
856 proto_item_set_text(ti->item,"%s",s);
857
858 /* copy the TreeItem userdata so we give it back */
859 lua_pushvalue(L, 1);
860
861 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
862}
863
864WSLUA_METHODstatic int TreeItem_append_text(lua_State *L) {
865 /* Appends text to the label.
866
867 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
868 */
869#define WSLUA_ARG_TreeItem_append_text_TEXT2 2 /* The text to be appended. */
870 TreeItem ti = checkTreeItem(L,1);
871 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_append_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
872
873 proto_item_append_text(ti->item,"%s",s);
874
875 /* copy the TreeItem userdata so we give it back */
876 lua_pushvalue(L, 1);
877
878 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
879}
880
881WSLUA_METHODstatic int TreeItem_prepend_text(lua_State *L) {
882 /* Prepends text to the label.
883
884 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
885 */
886#define WSLUA_ARG_TreeItem_prepend_text_TEXT2 2 /* The text to be prepended. */
887 TreeItem ti = checkTreeItem(L,1);
888 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_prepend_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
889
890 proto_item_prepend_text(ti->item,"%s",s);
891
892 /* copy the TreeItem userdata so we give it back */
893 lua_pushvalue(L, 1);
894
895 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
896}
897
898WSLUA_METHODstatic int TreeItem_add_expert_info(lua_State *L) {
899 /* Sets the expert flags of the item and adds expert info to the packet.
900
901 This function does *not* create a truly filterable expert info for a protocol.
902 Instead you should use `TreeItem.add_proto_expert_info()`.
903
904 Note: This function is provided for backwards compatibility only, and should not
905 be used in new Lua code. It may be removed in the future. You should only
906 use `TreeItem.add_proto_expert_info()`.
907 */
908#define WSLUA_OPTARG_TreeItem_add_expert_info_GROUP2 2 /* One of:
909 `PI_CHECKSUM`,
910 `PI_SEQUENCE`,
911 `PI_RESPONSE_CODE`,
912 `PI_REQUEST_CODE`,
913 `PI_UNDECODED`,
914 `PI_REASSEMBLE`,
915 `PI_MALFORMED`,
916 `PI_DEBUG`,
917 `PI_PROTOCOL`,
918 `PI_SECURITY`,
919 `PI_COMMENTS_GROUP`,
920 `PI_DECRYPTION`,
921 `PI_ASSUMPTION`,
922 `PI_DEPRECATED`,
923 `PI_RECEIVE`,
924 `PI_INTERFACE`,
925 or `PI_DISSECTOR_BUG`. */
926#define WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY3 3 /* One of:
927 `PI_COMMENT`,
928 `PI_CHAT`,
929 `PI_NOTE`,
930 `PI_WARN`,
931 or `PI_ERROR`. */
932#define WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4 4 /* The text for the expert info display. */
933 TreeItem ti = checkTreeItem(L,1);
934 int group = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_GROUP2,PI_DEBUG0x08000000);
935 int severity = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY3,PI_CHAT0x00200000);
936 expert_field* ei_info = wslua_get_expert_field(group, severity);
937 const char* str;
938
939 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4) {
940 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4);
941 expert_add_info_format(lua_pinfo, ti->item, ei_info, "%s", str);
942 } else {
943 expert_add_info(lua_pinfo, ti->item, ei_info);
944 }
945
946 /* copy the TreeItem userdata so we give it back */
947 lua_pushvalue(L, 1);
948
949 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
950}
951
952WSLUA_METHODstatic int TreeItem_add_proto_expert_info(lua_State *L) {
953 /* Sets the expert flags of the tree item and adds expert info to the packet. */
954#define WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
955#define WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3 3 /* Text for the expert info display
956 (default is to use the registered
957 text). */
958 TreeItem ti = checkTreeItem(L,1);
959 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2);
960 const char* str;
961
962 if (expert->ids.ei == EI_INIT_EI0 || expert->ids.hf == EI_INIT_HF0) {
963 luaL_error(L, "ProtoExpert is not registered");
964 return 0;
965 }
966
967 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3) {
968 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3);
969 expert_add_info_format(lua_pinfo, ti->item, &expert->ids, "%s", str);
970 } else {
971 expert_add_info(lua_pinfo, ti->item, &expert->ids);
972 }
973
974 /* copy the TreeItem userdata so we give it back */
975 lua_pushvalue(L, 1);
976
977 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
978}
979
980WSLUA_METHODstatic int TreeItem_add_tvb_expert_info(lua_State *L) {
981 /* Sets the expert flags of the tree item and adds expert info to the packet
982 associated with the <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> bytes in the packet. */
983#define WSLUA_ARG_TreeItem_add_tvb_expert_info_EXPERT2 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
984#define WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3 3 /* The <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> object bytes to associate
985 the expert info with. */
986#define WSLUA_OPTARG_TreeItem_add_tvb_expert_info_TEXT4 4 /* Text for the expert info display
987 (default is to use the registered
988 text). */
989 TreeItem ti = checkTreeItem(L,1);
990 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2);
991 TvbRange tvbr;
992 const char* str;
993
994 if (expert->ids.ei == EI_INIT_EI0 || expert->ids.hf == EI_INIT_HF0) {
995 luaL_error(L, "ProtoExpert is not registered");
996 return 0;
997 }
998
999 tvbr = shiftTvbRange(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3);
1000 if (tvbr && tvbr->tvb.expired) {
1001 luaL_error(L,"expired tvb");
1002 return 0;
1003 }
1004
1005 if (!tvbr) {
1006 /* Not a TvbRange; use the Tvb if one was passed, otherwise the
1007 * Tvb of the current dissection. Don't modify the passed Tvb. */
1008 Tvb tvb = shiftTvb(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3);
1009 if (tvb && tvb->expired) {
1010 luaL_error(L,"expired tvb");
1011 return 0;
1012 }
1013 tvbr = wmem_new0(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc0((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
1014 tvbr->tvb.ws_tvb = tvb ? tvb->ws_tvb : lua_tvb;
1015 tvbr->offset = 0;
1016 tvbr->len = 0;
1017 }
1018
1019 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3) {
1020 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3);
1021 proto_tree_add_expert_format(ti->tree, lua_pinfo, &expert->ids,
1022 tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len,
1023 "%s", str);
1024 } else {
1025 proto_tree_add_expert(ti->tree, lua_pinfo, &expert->ids,
1026 tvbr->tvb.ws_tvb, tvbr->offset, tvbr->len);
1027 }
1028
1029 /* copy the TreeItem userdata so we give it back */
1030 lua_pushvalue(L, 1);
1031
1032 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1033}
1034
1035
1036/* WSLUA_ATTRIBUTE TreeItem_visible RO Get the <<lua_class_TreeItem,`TreeItem`>>'s subtree visibility status (boolean). */
1037static int TreeItem_get_visible(lua_State* L) {
1038 TreeItem ti = checkTreeItem(L,1);
1039
1040 if (ti->tree) {
1041 lua_pushboolean(L, PTREE_DATA(ti->tree)((ti->tree)->tree_data)->visible);
1042 }
1043 else {
1044 lua_pushboolean(L, false0);
1045 }
1046
1047 return 1;
1048}
1049
1050
1051/* WSLUA_ATTRIBUTE TreeItem_generated RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s generated state (boolean). */
1052static int TreeItem_get_generated(lua_State* L) {
1053 TreeItem ti = checkTreeItem(L,1);
1054
1055 lua_pushboolean(L, proto_item_is_generated(ti->item));
1056
1057 return 1;
1058}
1059
1060/* the following is used as both a method and attribute. As a method it defaults
1061 to setting the value, because that's what it used to do before. */
1062WSLUA_METHODstatic int TreeItem_set_generated(lua_State *L) {
1063 /* Marks the <<lua_class_TreeItem,`TreeItem`>> as a generated field (with data inferred but not contained in the packet).
1064
1065 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1066 */
1067#define WSLUA_OPTARG_TreeItem_set_generated_BOOL2 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1068 generated flag, else clears it (default=true) */
1069 TreeItem ti = checkTreeItem(L,1);
1070 bool_Bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_generated_BOOL2, true1);
1071
1072 if (set) {
1073 proto_item_set_generated(ti->item);
1074 } else {
1075 if (ti->item)
1076 FI_RESET_FLAG(PITEM_FINFO(ti->item), FI_GENERATED)do { if (((ti->item)->finfo)) (((ti->item)->finfo
))->flags = (((ti->item)->finfo))->flags & ~(
0x00000002); } while(0)
;
1077 }
1078
1079 /* copy the TreeItem userdata so we give it back */
1080 lua_pushvalue(L, 1);
1081
1082 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1083}
1084
1085/* WSLUA_ATTRIBUTE TreeItem_hidden RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s hidden state (boolean). */
1086static int TreeItem_get_hidden(lua_State* L) {
1087 TreeItem ti = checkTreeItem(L,1);
1088
1089 lua_pushboolean(L, proto_item_is_hidden(ti->item));
1090
1091 return 1;
1092}
1093
1094/* the following is used as both a method and attribute. As a method it defaults
1095 to setting the value, because that's what it used to do before. */
1096WSLUA_METHODstatic int TreeItem_set_hidden(lua_State *L) {
1097 /*
1098 Marks the <<lua_class_TreeItem,`TreeItem`>> as a hidden field (neither displayed nor used in filters).
1099 Deprecated
1100
1101 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1102 */
1103#define WSLUA_OPTARG_TreeItem_set_hidden_BOOL2 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1104 hidden flag, else clears it. Default is `true`. */
1105 TreeItem ti = checkTreeItem(L,1);
1106 bool_Bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_hidden_BOOL2, true1);
1107
1108 if (set) {
1109 proto_item_set_hidden(ti->item);
1110 } else {
1111 proto_item_set_visible(ti->item);
1112 }
1113
1114 /* copy the TreeItem userdata so we give it back */
1115 lua_pushvalue(L, 1);
1116
1117 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1118}
1119
1120/* WSLUA_ATTRIBUTE TreeItem_len RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created. */
1121static int TreeItem_get_len(lua_State* L) {
1122 TreeItem ti = checkTreeItem(L,1);
1123 unsigned len = 0;
1124
1125 /* XXX - this is *NOT* guaranteed to return a correct value! */
1126 len = proto_item_get_len(ti->item);
1127
1128 lua_pushinteger(L, (lua_Integer)len > 0 ? (lua_Integer)len : 0);
1129
1130 return 1;
1131}
1132
1133WSLUA_METHODstatic int TreeItem_set_len(lua_State *L) {
1134 /* Set <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created.
1135
1136 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1137 */
1138#define WSLUA_ARG_TreeItem_set_len_LEN2 2 /* The length to be used. */
1139 TreeItem ti = checkTreeItem(L,1);
1140 int len = (int)luaL_checkinteger(L,WSLUA_ARG_TreeItem_set_len_LEN2);
1141
1142 if (len < 0) {
1143 luaL_argerror(L,WSLUA_ARG_TreeItem_set_len_LEN2,"must be a positive value");
1144 return 0;
1145 }
1146
1147 proto_item_set_len(ti->item, len);
1148
1149 /* copy the TreeItem userdata so we give it back */
1150 lua_pushvalue(L, 1);
1151
1152 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1153}
1154
1155WSLUA_METHODstatic int TreeItem_referenced(lua_State *L) {
1156 /* Checks if a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> is referenced by a filter/tap/UI.
1157
1158 If this function returns `false`, it means that the field (or dissector) does not need to be dissected
1159 and can be safely skipped. By skipping a field rather than dissecting it, the dissector will
1160 usually run faster since Wireshark will not do extra dissection work when it doesn't need the field.
1161
1162 You can use this in conjunction with the TreeItem.visible attribute. This function will always return
1163 true when the TreeItem is visible. When it is not visible and the field is not referenced, you can
1164 speed up the dissection by not dissecting the field as it is not needed for display or filtering.
1165
1166 This function takes one parameter that can be a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>>.
1167 The <<lua_class_Dissector,`Dissector`>> form is useful when you need to decide whether to call a sub-dissector.
1168 */
1169#define WSLUA_ARG_TreeItem_referenced_PROTOFIELD2 2 /* The <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> to check if referenced. */
1170 TreeItem ti = checkTreeItem(L, 1);
1171 if (!ti) return 0;
1172 ProtoField f = shiftProtoField(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD2);
1173 if (f) {
1174 lua_pushboolean(L, proto_field_is_referenced(ti->tree, f->hfid));
1175 }
1176 else {
1177 Dissector d = checkDissector(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD2);
1178 if (!d) return 0;
1179 lua_pushboolean(L, proto_field_is_referenced(ti->tree, dissector_handle_get_protocol_index(d)));
1180 }
1181 WSLUA_RETURN(1)return (1); /* A boolean indicating if the ProtoField/Dissector is referenced */
1182}
1183
1184WSLUA_METHODstatic int TreeItem_get_child_count(lua_State *L) {
1185 /* Returns the number of direct child tree items.
1186
1187 This method counts and returns the number of direct children of this tree item.
1188 Only immediate children are counted; grandchildren and deeper descendants are not included.
1189
1190 [source,lua]
1191 ----
1192 local tree = root:add(myproto, tvbuf())
1193 tree:add("Child 1")
1194 tree:add("Child 2")
1195
1196 local count = tree:get_child_count()
1197 -- count is now 2
1198 ----
1199
1200 @since 4.7.0
1201 */
1202
1203 /* Retrieve and validate the TreeItem from Lua stack position 1 */
1204 TreeItem ti = checkTreeItem(L, 1);
1205 if (!ti) {
1206 return 0;
1207 }
1208
1209 int count = 0;
1210 proto_tree *tree = ti->tree;
1211
1212 if (tree) {
1213 /* Get the first child node from the proto_tree structure */
1214 proto_node *current = ((proto_node *)tree)->first_child;
1215
1216 /* Iterate through the linked list of children using the 'next' pointer */
1217 while (current) {
1218 count++;
1219 current = current->next; /* Move to next sibling */
1220 }
1221 }
1222
1223 /* Push the count as an integer onto the Lua stack */
1224 lua_pushinteger(L, count);
1225 WSLUA_RETURN(1)return (1); /* The number of child tree items. */
1226}
1227
1228WSLUA_METHODstatic int TreeItem_get_parent(lua_State *L) {
1229 /* Returns the parent tree item.
1230
1231 Returns the parent tree item of this item, or nil if this is a root item
1232 (i.e., a top-level tree item added directly to the protocol tree).
1233
1234 [source,lua]
1235 ----
1236 local parent_tree = root:add(myproto, tvbuf())
1237 local child_tree = parent_tree:add("Child")
1238
1239 local parent = child_tree:get_parent()
1240 -- parent is the same as parent_tree
1241
1242 local root_parent = parent_tree:get_parent()
1243 -- root_parent is nil (assuming parent_tree is a root item)
1244 ----
1245 @since 4.7.0
1246 */
1247
1248 /* Retrieve and validate the TreeItem from Lua stack */
1249 TreeItem ti = checkTreeItem(L, 1);
1250 if (!ti) {
1251 return 0;
1252 }
1253
1254 proto_item *parent = NULL((void*)0);
1255
1256 if (ti->item) {
1257 /* Use Wireshark's built-in function to get the parent proto_item */
1258 parent = proto_item_get_parent(ti->item);
1259 }
1260
1261 if (parent) {
1262 /* Parent exists - get its subtree (may be NULL if parent has no children) */
1263 proto_tree *parent_tree = proto_item_get_subtree(parent);
1264
1265 /* Create a new Lua TreeItem object wrapping the parent and push it to Lua */
1266 push_TreeItem(L, parent_tree, parent);
1267 } else {
1268 /* No parent exists - this is a root item, return nil */
1269 lua_pushnil(L);
1270 }
1271
1272 WSLUA_RETURN(1)return (1); /* The parent TreeItem, or nil if this is a root item. */
1273}
1274
1275WSLUA_METHODstatic int TreeItem_get_child(lua_State *L) {
1276 /* Returns the child tree item at the specified index.
1277
1278 Returns the direct child TreeItem at the given index using 0-based indexing.
1279 This provides random access to child items by their position.
1280
1281 [source,lua]
1282 ----
1283 local tree = root:add(myproto, tvbuf())
1284 tree:add("First child") -- index 0
1285 tree:add("Second child") -- index 1
1286 tree:add("Third child") -- index 2
1287
1288 local first = tree:get_child(0) -- Returns first child
1289 local second = tree:get_child(1) -- Returns second child
1290 local invalid = tree:get_child(5) -- Returns nil (out of range)
1291 ----
1292 @since 4.7.0
1293 */
1294
1295#define WSLUA_ARG_TreeItem_get_child_INDEX2 2 /* The index of the child (0-based). */
1296 /* Retrieve and validate the TreeItem */
1297 TreeItem ti = checkTreeItem(L, 1);
1298 if (!ti)
1299 return 0;
1300
1301 /* Get the index parameter from Lua (must be an integer) */
1302 lua_Integer index = luaL_checkinteger(L, WSLUA_ARG_TreeItem_get_child_INDEX2);
1303
1304 /* Validate index - must be non-negative for 0-based indexing */
1305 if (index < 0) {
1306 WSLUA_ARG_ERROR(TreeItem_get_child, INDEX, "index must be non-negative"){ luaL_argerror(L,2, "TreeItem_get_child" ": " "index must be non-negative"
); }
;
1307 }
1308
1309 proto_node *current = NULL((void*)0);
1310
1311 if (ti->tree) {
1312 /* Get the first child in the linked list */
1313 current = ((proto_node *)ti->tree)->first_child;
1314 }
1315
1316 /* Navigate to the index-th child by following the 'next' pointers */
1317 lua_Integer current_index = 0;
1318 while (current && current_index < index) {
1319 current = current->next; /* Move to next sibling */
1320 current_index++;
1321 }
1322
1323 if (current) {
1324 /* Child found at the specified index */
1325 /* Get the subtree (may be NULL if this node has no children) */
1326 proto_tree *child_tree = proto_item_get_subtree((proto_item *)current);
1327
1328 /* Create and push the TreeItem to Lua */
1329 push_TreeItem(L, child_tree, (proto_item *)current);
1330 } else {
1331 /* Index out of range - no child exists at this position */
1332 lua_pushnil(L);
1333 }
1334
1335 WSLUA_RETURN(1)return (1); /* The child TreeItem at the specified index, or nil if out of range. */
1336}
1337
1338/* Structure to hold iterator state with optional field name filters and recursion */
1339typedef struct
1340{
1341 proto_node *next_node; /* Next node to process in iteration */
1342 char **field_filters; /* Array of field name strings to match (e.g., "tcp.port") */
1343 unsigned num_filters; /* Number of filter strings in the array */
1344 bool_Bool recursive; /* If true, iterate through entire subtree depth-first */
1345 wmem_stack_t *children; /* For recursive depth-first traversal */
1346} TreeItem_iterator_state;
1347
1348/* Helper function for the children iterator with optional filtering and recursion */
1349static int TreeItem_children_iterator(lua_State *L) {
1350 /* Retrieve the iterator state from the closure's upvalue */
1351 TreeItem_iterator_state *state = (TreeItem_iterator_state *)lua_touserdata(L, lua_upvalueindex(1)((-(2147483647/2 + 1000)) - (1)));
1352 /* The TreeItem being iterated over; the nodes in the state, and the
1353 * state's allocations, are freed with the packet, when it expires. */
1354 TreeItem ti = toTreeItem(L, lua_upvalueindex(2)((-(2147483647/2 + 1000)) - (2)));
1355
1356 if (!ti || ti->expired) {
1357 return luaL_error(L, "expired TreeItem");
1358 }
1359
1360 /* Continue iterating while we have nodes to process */
1361 /* Either from current sibling chain OR from recursive stack */
1362 while (state->next_node || (state->recursive && wmem_stack_count(state->children)wmem_list_count(state->children) > 0)) {
1363 proto_node *node = NULL((void*)0); /* Node currently being processed */
1364
1365 if (state->next_node) {
1366 /* Process next node in current sibling chain */
1367 node = state->next_node;
1368 state->next_node = node->next; /* Advance to next sibling for next iteration */
1369 }
1370 else if (state->recursive && wmem_stack_count(state->children)wmem_list_count(state->children) > 0) {
1371 /* pop from children for recursive traversal */
1372 node = (proto_node *)wmem_stack_pop(state->children);
1373 }
1374 ws_assert(node != NULL)do { if ((1) && !(node != ((void*)0))) ws_log_fatal_full
("", LOG_LEVEL_ERROR, "epan/wslua/wslua_tree.c", 1374, __func__
, "assertion failed: %s", "node != ((void*)0)"); } while (0)
;
1375
1376 /* IMPORTANT: For recursive mode, always add children regardless of filter match
1377 * This ensures that even if the current node doesn't match the filter,
1378 * its children are still searched recursively (depth-first traversal)
1379 *
1380 * Example: If we filter for "tcp.port" but current node is "tcp.flags",
1381 * we still need to check if "tcp.flags" has "tcp.port" children
1382 */
1383 if (state->recursive) {
1384 proto_tree *subtree = proto_item_get_subtree((proto_item *)node);
1385 if (subtree) {
1386 /* Collect all children first (needed for reverse-order pushing) */
1387 proto_node *child;
1388 wmem_stack_t *children = wmem_stack_new(lua_pinfo->pool)wmem_list_new(lua_pinfo->pool);
1389
1390 /* Count and collect all children in forward order */
1391 for (child = ((proto_node *)subtree)->first_child; child != NULL((void*)0); child = child->next) {
1392 wmem_stack_push(children, (void *)child)wmem_list_prepend((children), ((void *)child));
1393 }
1394
1395 /* Push children in REVERSE order to stack */
1396 /* This ensures depth-first left-to-right traversal */
1397 /* (first child is on top of stack, gets popped first) */
1398 while (wmem_stack_count(children)wmem_list_count(children) > 0) {
1399 wmem_stack_push(state->children, wmem_stack_pop(children))wmem_list_prepend((state->children), (wmem_stack_pop(children
)))
;
1400 }
1401
1402 wmem_destroy_stack(children)wmem_destroy_list(children);
1403 }
1404 }
1405
1406 /* Check if this node matches the filter criteria */
1407 bool_Bool matches = false0;
1408 if (state->num_filters > 0) {
1409 /* Filters are specified - check if node's field name matches any filter */
1410 field_info *finfo = node->finfo;
1411
1412 /* Ensure node has valid field_info with abbreviated name */
1413 if (finfo && finfo->hfinfo && finfo->hfinfo->abbrev) {
1414 /* Check against all filter strings (OR logic) */
1415 for (unsigned i = 0; i < state->num_filters; i++) {
1416 if (strcmp(finfo->hfinfo->abbrev, state->field_filters[i]) == 0) {
1417 matches = true1;
1418 break; /* Found match, no need to check remaining filters */
1419 }
1420 }
1421 }
1422 /* If finfo is NULL or has no abbrev, matches remains false */
1423 } else {
1424 /* No filters specified - return all children/descendants */
1425 matches = true1;
1426 }
1427
1428 /* Only return matching nodes to Lua, but continue processing regardless
1429 * (children were already added above for recursive mode) */
1430 if (matches) {
1431 /* Get the subtree for this matching node (may be NULL) */
1432 proto_tree *child_tree = proto_item_get_subtree((proto_item *)node);
1433
1434 /* Push matching TreeItem to Lua stack */
1435 push_TreeItem(L, child_tree, (proto_item *)node);
1436 return 1; /* Return 1 value to Lua iterator */
1437 }
1438
1439 /* If no match, continue to next node
1440 * Children are already on stack for recursive mode,
1441 * ensuring we don't miss matching descendants */
1442 }
1443
1444 /* No more nodes to process - iteration complete */
1445 return 0; /* Return no values - signals end of iteration to Lua */
1446}
1447
1448/* Garbage collector for the iterator state.
1449 * Currently does nothing but kept for completeness.
1450 */
1451static int TreeItem_iterator_state_gc(lua_State *L _U___attribute__((unused))) {
1452 //TreeItem_iterator_state *state = (TreeItem_iterator_state *)lua_touserdata(L, 1);
1453
1454 /* The filter strings array and the recursion structure were allocated from
1455 * lua_pinfo->pool and are freed automatically by Wireshark.
1456 * The state struct itself is freed by Lua's garbage collection.
1457 */
1458 return 0;
1459}
1460
1461WSLUA_METHODstatic int TreeItem_children(lua_State *L) {
1462 /* Returns an iterator function to iterate over child tree items.
1463
1464 Returns an iterator function that can be used in a Lua for loop to iterate
1465 over children of this tree item. Supports optional filtering and recursive traversal.
1466
1467 The basic usage iterates over direct children only:
1468 [source,lua]
1469 ----
1470 for child in tree:children() do
1471 print("Child: " .. tostring(child))
1472 end
1473 ----
1474
1475 You can filter by field names to only get children with specific fields:
1476 [source,lua]
1477 ----
1478 -- Single field filter
1479 for child in tree:children("tcp.flags") do
1480 print("TCP flags child: " .. tostring(child))
1481 end
1482
1483 -- Multiple field filters
1484 for child in tree:children({"tcp.port", "tcp.srcport", "tcp.dstport"}) do
1485 print("TCP port child: " .. tostring(child))
1486 end
1487 ----
1488
1489 Enable recursive iteration to traverse the entire subtree in depth-first order:
1490 [source,lua]
1491 ----
1492 -- Recursive iteration without filter
1493 for child in tree:children(nil, true) do
1494 print("Descendant: " .. tostring(child))
1495 end
1496
1497 -- Recursive iteration with field filter
1498 for child in tree:children("tcp.flags", true) do
1499 print("TCP flags anywhere in subtree: " .. tostring(child))
1500 end
1501 ----
1502
1503 When using recursive mode with filters, the iterator searches through all descendants
1504 even if parent nodes don't match the filter, ensuring no matching children are missed.
1505
1506 IMPORTANT: Field extractors must still be created for the fields you want to iterate over.
1507 Wireshark optimizes dissection by only creating tree items for fields that are explicitly
1508 requested through field extractors, display filters, or taps. Without proper field extractors,
1509 the fields may not exist in the dissection tree and will not be found by this iterator.
1510
1511 Example of proper field extractor setup:
1512 [source,lua]
1513 ----
1514 -- Define field extractors first
1515 local tcp_flags_extractor = Field.new("tcp.flags")
1516 local tcp_port_extractor = Field.new("tcp.port")
1517
1518 -- Then use tree navigation (extractors ensure fields exist in tree)
1519 for child in tree:children("tcp.flags") do
1520 local field_info = child:get_field_info()
1521 print("TCP Flags:", field_info.value)
1522 end
1523 ----
1524 @since 4.7.0
1525 */
1526
1527#define WSLUA_OPTARG_TreeItem_children_FIELD_FILTER2 2 /* Optional field name(s) to filter by (string or table of strings). */
1528#define WSLUA_OPTARG_TreeItem_children_RECURSIVE3 3 /* Optional boolean to enable recursive (depth-first) iteration. Default is false. */
1529
1530 /* Retrieve and validate the TreeItem */
1531 TreeItem ti = checkTreeItem(L, 1);
1532 if (!ti) {
1533 THROW_LUA_ERROR("not a TreeItem!")except_throwf(1, (6), "not a TreeItem!");
1534 return 0;
1535 }
1536 if (ti->expired) {
1537 THROW_LUA_ERROR("expired TreeItem")except_throwf(1, (6), "expired TreeItem");
1538 return 0;
1539 }
1540
1541 unsigned num_filters = 0;
1542
1543 switch (lua_type(L, WSLUA_OPTARG_TreeItem_children_FIELD_FILTER2)) {
1544 case LUA_TSTRING4: /* Single string */
1545 num_filters = 1;
1546 break;
1547
1548 case LUA_TNIL0: /* Explicitly nil */
1549 case LUA_TNONE(-1): /* Not given at all */
1550 break;
1551
1552 case LUA_TTABLE5: /* Table, must be a table of strings */
1553 {
1554 num_filters = (unsigned)lua_rawlen(L, WSLUA_OPTARG_TreeItem_children_FIELD_FILTER2);
1555 for (unsigned i = 1; i <= num_filters; i++) {
1556 lua_rawgeti(L, WSLUA_OPTARG_TreeItem_children_FIELD_FILTER2, i);
1557 if (lua_type(L, -1) != LUA_TSTRING4) {
1558 luaL_error(L, "TreeItem:children() field filter table entries must be strings");
1559 return 0;
1560 }
1561 lua_pop(L, 1)lua_settop(L, -(1)-1);
1562 }
1563 }
1564 break;
1565
1566 default:
1567 luaL_error(L, "TreeItem:children() field filter must be a string or table of strings");
1568 return 0;
1569 }
1570
1571 bool_Bool recursive = wslua_toboolean(L, WSLUA_OPTARG_TreeItem_children_RECURSIVE3);
1572
1573 proto_node *first_child = NULL((void*)0);
1574
1575 if (ti->tree) {
1576 /* Get the first child from the tree's linked list */
1577 first_child = ((proto_node *)ti->tree)->first_child;
1578 }
1579
1580 /* Create the iterator state userdata that will be used by the iterator closure */
1581 /* This userdata will be garbage collected when the iterator is no longer referenced */
1582 TreeItem_iterator_state *state = (TreeItem_iterator_state *)lua_newuserdata(L, sizeof(TreeItem_iterator_state))lua_newuserdatauv(L,sizeof(TreeItem_iterator_state),1);
1583
1584 /* Initialize all state fields to safe defaults */
1585 state->next_node = first_child; /* Start with first child */
1586 state->num_filters = num_filters;
1587 state->field_filters = num_filters > 0 ? wmem_alloc_array(lua_pinfo->pool, char*, num_filters)((char**)wmem_alloc((lua_pinfo->pool), (((((num_filters)) <=
0) || ((size_t)sizeof(char*) > (9223372036854775807L / (size_t
)((num_filters))))) ? 0 : (sizeof(char*) * ((num_filters)))))
)
: NULL((void*)0);
1588 state->recursive = recursive;
1589 state->children = recursive ? wmem_stack_new(lua_pinfo->pool)wmem_list_new(lua_pinfo->pool) : NULL((void*)0);
1590
1591 /* Set up garbage collection metatable for the state userdata */
1592 /* This ensures proper cleanup when iterator is no longer referenced */
1593 lua_newtable(L)lua_createtable(L, 0, 0); /* Create metatable */
1594 lua_pushcfunction(L, TreeItem_iterator_state_gc)lua_pushcclosure(L, (TreeItem_iterator_state_gc), 0);
1595 lua_setfield(L, -2, "__gc"); /* Set __gc metamethod */
1596 lua_setmetatable(L, -2); /* Apply metatable to userdata */
1597
1598 /* Check number of filters we were given */
1599 if (num_filters == 1) {
1600 /* We got passed a single string */
1601 state->field_filters[0] = wmem_strdup(lua_pinfo->pool, lua_tostring(L, WSLUA_OPTARG_TreeItem_children_FIELD_FILTER)lua_tolstring(L, (2), ((void*)0)));
1602 }
1603 else if (num_filters > 1) {
1604 /* We got passed a table, we checked above that it was all strings */
1605 for (unsigned i = 0; i < num_filters; i++) {
1606 lua_rawgeti(L, WSLUA_OPTARG_TreeItem_children_FIELD_FILTER2, i+1);
1607 state->field_filters[i] = wmem_strdup(lua_pinfo->pool, lua_tostring(L, -1)lua_tolstring(L, (-1), ((void*)0)));
1608 lua_pop(L, 1)lua_settop(L, -(1)-1);
1609 }
1610 }
1611
1612 /* Push the iterator function as a closure with state and the TreeItem
1613 * as upvalues */
1614 /* The state userdata is kept alive as long as the closure exists */
1615 lua_pushvalue(L, 1);
1616 lua_pushcclosure(L, TreeItem_children_iterator, 2);
1617
1618 WSLUA_RETURN(1)return (1); /* An iterator function for use in Lua for loops. */
1619}
1620
1621WSLUA_METHODstatic int TreeItem_get_field_info(lua_State *L) {
1622 /* Returns the FieldInfo object associated with this tree item.
1623
1624 Returns a FieldInfo object that provides access to the underlying field
1625 information including name, abbreviated name, type, value, data offset,
1626 length, and other protocol field properties.
1627
1628 This is particularly useful for extracting actual field values and
1629 metadata from tree items during packet analysis.
1630
1631 [source,lua]
1632 ----
1633 for child in tree:children() do
1634 local field_info = child:get_field_info()
1635 if field_info then
1636 print("Field name: " .. field_info.name)
1637 print("Field abbrev: " .. field_info.abbrev)
1638 print("Field type: " .. field_info.type)
1639 print("Field value: " .. tostring(field_info.value))
1640 print("Field offset: " .. field_info.offset)
1641 print("Field len: " .. field_info.len)
1642 else
1643 print("No field info (text-only or generated item)")
1644 end
1645 end
1646 ----
1647
1648 NOTE: Field extractors are still required to ensure fields exist in the dissection tree.
1649 This method only provides access to field information for tree items that already exist.
1650
1651 @since 4.7.0
1652 */
1653
1654 /* Retrieve and validate the TreeItem */
1655 TreeItem ti = checkTreeItem(L, 1);
1656 if (!ti) {
1657 THROW_LUA_ERROR("not a TreeItem!")except_throwf(1, (6), "not a TreeItem!");
1658 return 0;
1659 }
1660 if (ti->expired) {
1661 THROW_LUA_ERROR("expired TreeItem")except_throwf(1, (6), "expired TreeItem");
1662 return 0;
1663 }
1664
1665 field_info *finfo = NULL((void*)0);
1666
1667 /* Get field_info from the proto_item */
1668 if (ti->item) {
1669 /* Cast proto_item to proto_node to access finfo member */
1670 proto_node *node = (proto_node *)ti->item;
1671 finfo = node->finfo; /* May be NULL for text-only tree items */
1672 }
1673
1674 if (finfo) {
1675 /* Valid field_info exists - create and push FieldInfo Lua object */
1676 /* This makes all field properties accessible from Lua */
1677 push_FieldInfo(L, finfo);
1678 } else {
1679 /* No field_info - this is a text-only tree item or generated content */
1680 lua_pushnil(L);
1681 }
1682
1683 WSLUA_RETURN(1)return (1); /* The FieldInfo object, or nil if not available. */
1684}
1685
1686WSLUA_METAMETHODstatic int TreeItem__tostring(lua_State* L) {
1687 /* Returns a short label of the form `TreeItem: <abbrev>` for an
1688 attached field, `TreeItem: (root)` for a text-only/root tree,
1689 or `TreeItem: (no item)` / `TreeItem: (expired)` /
1690 `TreeItem: (null)` for the degenerate cases. The previous
1691 form dumped only boolean flags (expired/item/tree/same),
1692 which were not very useful for identifying which TreeItem
1693 the debugger is looking at. */
1694 TreeItem ti = toTreeItem(L,1);
1695
1696 if (!ti) {
1697 lua_pushstring(L, "TreeItem: (null)");
1698 } else if (ti->expired) {
1699 lua_pushstring(L, "TreeItem: (expired)");
1700 } else if (!ti->item) {
1701 lua_pushstring(L, "TreeItem: (no item)");
1702 } else {
1703 proto_node *node = (proto_node *)ti->item;
1704 field_info *finfo = node ? node->finfo : NULL((void*)0);
1705 if (finfo && finfo->hfinfo && finfo->hfinfo->abbrev) {
1706 lua_pushfstring(L, "TreeItem: %s", finfo->hfinfo->abbrev);
1707 } else {
1708 lua_pushstring(L, "TreeItem: (root)");
1709 }
1710 }
1711
1712 return 1;
1713}
1714
1715/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1716static int TreeItem__gc(lua_State* L) {
1717 TreeItem ti = toTreeItem(L,1);
1718 if (!ti) return 0;
1719 if (!ti->expired)
1720 ti->expired = true1;
1721 else
1722 g_free(ti)(__builtin_object_size ((ti), 0) != ((size_t) - 1)) ? g_free_sized
(ti, __builtin_object_size ((ti), 0)) : (g_free) (ti)
;
1723 return 0;
1724}
1725
1726WSLUA_ATTRIBUTESstatic const wslua_attribute_table TreeItem_attributes[] = {
1727 WSLUA_ATTRIBUTE_RWREG(TreeItem,generated){ "generated", TreeItem_get_generated, TreeItem_set_generated
}
,
1728 WSLUA_ATTRIBUTE_RWREG(TreeItem,hidden){ "hidden", TreeItem_get_hidden, TreeItem_set_hidden },
1729 WSLUA_ATTRIBUTE_RWREG(TreeItem,len){ "len", TreeItem_get_len, TreeItem_set_len },
1730 WSLUA_ATTRIBUTE_RWREG(TreeItem,text){ "text", TreeItem_get_text, TreeItem_set_text },
1731 WSLUA_ATTRIBUTE_ROREG(TreeItem,visible){ "visible", TreeItem_get_visible, ((void*)0) },
1732 { NULL((void*)0), NULL((void*)0), NULL((void*)0) }
1733};
1734
1735WSLUA_METHODSstatic const luaL_Reg TreeItem_methods[] = {
1736 WSLUA_CLASS_FNREG(TreeItem, add_packet_field){ "add_packet_field", TreeItem_add_packet_field },
1737 WSLUA_CLASS_FNREG(TreeItem, add){ "add", TreeItem_add },
1738 WSLUA_CLASS_FNREG(TreeItem, add_le){ "add_le", TreeItem_add_le },
1739 WSLUA_CLASS_FNREG(TreeItem, set_text){ "set_text", TreeItem_set_text },
1740 WSLUA_CLASS_FNREG(TreeItem, append_text){ "append_text", TreeItem_append_text },
1741 WSLUA_CLASS_FNREG(TreeItem, prepend_text){ "prepend_text", TreeItem_prepend_text },
1742 WSLUA_CLASS_FNREG(TreeItem, add_expert_info){ "add_expert_info", TreeItem_add_expert_info },
1743 WSLUA_CLASS_FNREG(TreeItem, add_proto_expert_info){ "add_proto_expert_info", TreeItem_add_proto_expert_info },
1744 WSLUA_CLASS_FNREG(TreeItem, add_tvb_expert_info){ "add_tvb_expert_info", TreeItem_add_tvb_expert_info },
1745 WSLUA_CLASS_FNREG(TreeItem, set_generated){ "set_generated", TreeItem_set_generated },
1746 WSLUA_CLASS_FNREG(TreeItem, set_hidden){ "set_hidden", TreeItem_set_hidden },
1747 WSLUA_CLASS_FNREG(TreeItem, set_len){ "set_len", TreeItem_set_len },
1748 WSLUA_CLASS_FNREG(TreeItem, referenced){ "referenced", TreeItem_referenced },
1749 WSLUA_CLASS_FNREG(TreeItem, get_child_count){ "get_child_count", TreeItem_get_child_count },
1750 WSLUA_CLASS_FNREG(TreeItem, get_parent){ "get_parent", TreeItem_get_parent },
1751 WSLUA_CLASS_FNREG(TreeItem, get_child){ "get_child", TreeItem_get_child },
1752 WSLUA_CLASS_FNREG(TreeItem, children){ "children", TreeItem_children },
1753 WSLUA_CLASS_FNREG(TreeItem, get_field_info){ "get_field_info", TreeItem_get_field_info },
1754 {NULL((void*)0), NULL((void*)0)}};
1755
1756WSLUA_METAstatic const luaL_Reg TreeItem_meta[] = {
1757 WSLUA_CLASS_MTREG(TreeItem,tostring){ "__" "tostring", TreeItem__tostring },
1758 { NULL((void*)0), NULL((void*)0) }
1759};
1760
1761int TreeItem_register(lua_State *L) {
1762 int* etts[] = { &wslua_ett };
1763 wslua_ett = -1; /* Reset to support reload Lua plugins */
1764 WSLUA_REGISTER_CLASS_WITH_ATTRS(TreeItem){ const wslua_class TreeItem_class = { .name = "TreeItem", .class_methods
= TreeItem_methods, .class_meta = TreeItem_meta, .instance_methods
= TreeItem_methods, .instance_meta = TreeItem_meta, .attrs =
TreeItem_attributes }; wslua_register_class(L, &TreeItem_class
); (lua_getfield(L, (-(2147483647/2 + 1000)), ("TreeItem")));
lua_pushcclosure(L, (TreeItem__gc), 0); lua_setfield(L, -2, "__gc"
); lua_settop(L, -(1)-1); }
;
1765 if (outstanding_TreeItem != NULL((void*)0)) {
1766 g_ptr_array_unref(outstanding_TreeItem);
1767 }
1768 outstanding_TreeItem = g_ptr_array_new();
1769 proto_register_subtree_array(etts,1);
1770 return 0;
1771}
1772
1773/*
1774 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1775 *
1776 * Local variables:
1777 * c-basic-offset: 4
1778 * tab-width: 8
1779 * indent-tabs-mode: nil
1780 * End:
1781 *
1782 * vi: set shiftwidth=4 tabstop=8 expandtab:
1783 * :indentSize=4:tabSize=8:noTabs=true:
1784 */