Bug Summary

File:builds/wireshark/wireshark/epan/wslua/wslua_tree.c
Warning:line 751, 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-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/lua5.4 -isystem /builds/wireshark/wireshark/build/epan/wslua -isystem /builds/wireshark/wireshark/epan/wslua -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-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../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-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -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 -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -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 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/lua5.4 -isystem /builds/wireshark/wireshark/build/epan/wslua -isystem /builds/wireshark/wireshark/epan/wslua -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/wslua/wslua_tree.c -o /builds/wireshark/wireshark/sbout/2024-11-30-100238-3913-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-30-100238-3913-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 <[email protected]>
7 * (c) 2008, Balint Reczey <[email protected]>
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <[email protected]>
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 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, (-1000000 - 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, (-1000000 - 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, (-1000000 - 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 int 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 {
187 const uint8_t *ret;
188 int len;
189 item = proto_tree_add_item_ret_string_and_length(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
190 tvbr->offset, tvbr->len, encoding,
191 NULL((void*)0), &ret, &len);
192 lua_pushstring(L, ret);
193 lua_pushinteger(L, tvbr->offset + len);
194 wmem_free(NULL((void*)0), (void*)ret);
195 }
196 break;
197
198 case FT_STRINGZ:
199 {
200 const uint8_t *ret;
201 int len;
202 item = proto_tree_add_item_ret_string_and_length(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
203 tvbr->offset, -1, encoding,
204 NULL((void*)0), &ret, &len);
205 lua_pushstring(L, ret);
206 lua_pushinteger(L, tvbr->offset + len);
207 wmem_free(NULL((void*)0), (void*)ret);
208 }
209 break;
210
211 case FT_FLOAT:
212 {
213 float ret;
214 item = proto_tree_add_item_ret_float(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
215 tvbr->offset, tvbr->len, encoding,
216 &ret);
217 lua_pushnumber(L, (lua_Number)ret);
218 lua_pushinteger(L, tvbr->offset + tvbr->len);
219 }
220 break;
221
222 case FT_DOUBLE:
223 {
224 double ret;
225 item = proto_tree_add_item_ret_double(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
226 tvbr->offset, tvbr->len, encoding,
227 &ret);
228 lua_pushnumber(L, (lua_Number)ret);
229 lua_pushinteger(L, tvbr->offset + tvbr->len);
230 }
231 break;
232
233 case FT_IPv4:
234 {
235 Address addr = g_new(address,1)((address *) g_malloc_n ((1), sizeof (address)));
236 ws_in4_addr ret;
237 item = proto_tree_add_item_ret_ipv4(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
238 tvbr->offset, tvbr->len, encoding,
239 &ret);
240 alloc_address_wmem(NULL((void*)0), addr, AT_IPv4, sizeof(ret), &ret);
241 pushAddress(L, addr);
242 lua_pushinteger(L, tvbr->offset + tvbr->len);
243 }
244 break;
245
246 case FT_IPv6:
247 {
248 Address addr = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
249 ws_in6_addr ret;
250 item = proto_tree_add_item_ret_ipv6(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
251 tvbr->offset, tvbr->len, encoding,
252 &ret);
253 alloc_address_wmem(NULL((void*)0), addr, AT_IPv6, sizeof(ret), &ret);
254 pushAddress(L, addr);
255 lua_pushinteger(L, tvbr->offset + tvbr->len);
256 }
257 break;
258
259 case FT_ETHER:
260 {
261 Address addr = g_new(address, 1)((address *) g_malloc_n ((1), sizeof (address)));
262 uint8_t bytes[FT_ETHER_LEN6];
263
264 item = proto_tree_add_item_ret_ether(tree_item->tree, hfid, tvbr->tvb->ws_tvb,
265 tvbr->offset, tvbr->len, encoding,
266 bytes);
267 alloc_address_wmem(NULL((void*)0), addr, AT_ETHER, sizeof(bytes), bytes);
268 pushAddress(L, addr);
269 lua_pushinteger(L, tvbr->offset + tvbr->len);
270 }
271 break;
272
273 default:
274 item = proto_tree_add_item(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, encoding);
275 lua_pushnil(L);
276 lua_pushnil(L);
277 break;
278 }
279
280 if (ret_err) *ret_err = err;
281
282 return item;
283}
284
285WSLUA_METHODstatic int TreeItem_add_packet_field(lua_State *L) {
286 /*
287 Adds a new child tree for the given <<lua_class_ProtoField,`ProtoField`>> object to this tree item,
288 returning the new child <<lua_class_TreeItem,`TreeItem`>>.
289
290 Unlike `TreeItem:add()` and `TreeItem:add_le()`, the <<lua_class_ProtoField,`ProtoField`>> argument
291 is not optional, and cannot be a `Proto` object. Instead, this function always
292 uses the <<lua_class_ProtoField,`ProtoField`>> to determine the type of field to extract from the
293 passed-in `TvbRange`, highlighting the relevant bytes in the Packet Bytes pane
294 of the GUI (if there is a GUI), etc. If no <<lua_class_TvbRange,`TvbRange`>>is given, no bytes are
295 highlighted and the field's value cannot be determined; the <<lua_class_ProtoField,`ProtoField`>> must
296 have been defined/created not to have a length in such a case, or an error will
297 occur. For backwards-compatibility reasons the `encoding` argument, however,
298 must still be given.
299
300 Unlike `TreeItem:add()` and `TreeItem:add_le()`, this function performs both
301 big-endian and little-endian decoding, by setting the `encoding` argument to
302 be `ENC_BIG_ENDIAN` or `ENC_LITTLE_ENDIAN`.
303
304 The signature of this function:
305
306 [source,lua]
307 ----
308 tree_item:add_packet_field(proto_field [,tvbrange], encoding, ...)
309 ----
310
311 This function returns more than just the new child <<lua_class_TreeItem,`TreeItem`>>.
312 The child is the first return value, so that function chaining will still work; but it
313 also returns more information. The second return is the value of the extracted field
314 (i.e., a number, `UInt64`, `Address`, etc.). The third return is is the offset where
315 data should be read next. This is useful when the length of the field is not known in
316 advance. The additional return values may be null if the field type is not well supported
317 in the Lua API.
318
319 This function can extract a <<lua_class_ProtoField,`ProtoField`>> of type `ftypes.BYTES`
320 or `ftypes.ABSOLUTE_TIME` from a string in the `TvbRange` in ASCII-based and similar
321 encodings. For example, a `ProtoField` of `ftypes.BYTES` can be extracted from a `TvbRange`
322 containing the ASCII string "a1b2c3d4e5f6", and it will correctly decode the ASCII both in the
323 tree as well as for the second return value, which will be a <<lua_class_ByteArray,`ByteArray`>>.
324 To do so, you must set the `encoding` argument of this function to the appropriate string `ENC_*`
325 value, bitwise-or'd (or added) with the `ENC_STR_HEX` value and one or more `ENC_SEP_XXX` values
326 indicating which encodings are allowed. For `ftypes.ABSOLUTE_TIME`, one of the `ENC_ISO_8601_*`
327 encodings or `ENC_IMF_DATE_TIME` must be used, and the second return value is a <<lua_class_NSTime,`NSTime`>>.
328 Only single-byte ASCII digit string encodings such as `ENC_ASCII` and `ENC_UTF_8` can be used for this.
329
330 For example, assuming the <<lua_class_Tvb,`Tvb`>> named "`tvb`" contains the string "abcdef"
331 (61 62 63 64 65 66 in hex):
332
333 [source,lua]
334 ----
335 -- this is done earlier in the script
336 local myfield = ProtoField.new("Transaction ID", "myproto.trans_id", ftypes.BYTES)
337 myproto.fields = { myfield }
338
339 -- this is done inside a dissector, post-dissector, or heuristic function
340 -- child will be the created child tree, and value will be the ByteArray "abcdef" or nil on failure
341 local child, value = tree:add_packet_field(myfield, tvb:range(0,6), ENC_UTF_8 + ENC_STR_HEX + ENC_SEP_NONE)
342 ----
343
344 */
345#define WSLUA_ARG_TreeItem_add_packet_field_PROTOFIELD2 2 /* The ProtoField field object to add to the tree. */
346#define WSLUA_OPTARG_TreeItem_add_packet_field_TVBRANGE3 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
347#define WSLUA_ARG_TreeItem_add_packet_field_ENCODING4 4 /* The field's encoding in the `TvbRange`. */
348#define WSLUA_OPTARG_TreeItem_add_packet_field_LABEL5 5 /* One or more strings to append to the created <<lua_class_TreeItem,`TreeItem`>>. */
349 volatile TvbRange tvbr;
350 ProtoField field;
351 int hfid;
352 volatile int ett;
353 ftenum_t type;
354 TreeItem tree_item = shiftTreeItem(L,1);
355 unsigned encoding;
356 proto_item* item = NULL((void*)0);
357 volatile int nargs;
358 volatile int err = 0;
359 const char *volatile error = NULL((void*)0);
360
361 if (!tree_item) {
362 return luaL_error(L,"not a TreeItem!");
363 }
364 if (tree_item->expired) {
365 luaL_error(L,"expired TreeItem");
366 return 0;
367 }
368
369 if (! ( field = shiftProtoField(L,1) ) ) {
370 luaL_error(L,"TreeField:add_packet_field not passed a ProtoField");
371 return 0;
372 }
373 if (field->hfid == -2) {
374 luaL_error(L, "ProtoField %s unregistered (not added to a Proto.fields attribute)", field->abbrev);
375 }
376 hfid = field->hfid;
377 type = field->type;
378 ett = field->ett;
379
380 tvbr = shiftTvbRange(L,1);
381 if (!tvbr) {
382 /* No TvbRange specified */
383 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
384 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb)((struct _wslua_tvb*)wmem_alloc((lua_pinfo->pool), sizeof(
struct _wslua_tvb)))
;
385 tvbr->tvb->ws_tvb = lua_tvb;
386 tvbr->offset = 0;
387 tvbr->len = 0;
388 }
389
390 encoding = wslua_checkuint(L,1)(unsigned) ( luaL_checkinteger(L,1) );
391 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
392
393 /* get the number of additional args before we add more to the stack */
394 nargs = lua_gettop(L);
395
396 /* XXX: why is this being done? If the length was -1, FT_STRINGZ figures out
397 * the right length in tvb_get_stringz_enc(); if it was 0, it should remain zero;
398 * if it was greater than zero, then it's the length the caller wanted.
399 */
400 if (type == FT_STRINGZ) {
401 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
402
403 case ENC_UTF_160x00000004:
404 case ENC_UCS_20x00000006:
405 tvbr->len = tvb_unicode_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
406 break;
407
408 default:
409 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
410 luaL_error(L,"out of bounds");
411 return 0;
412 }
413 tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
414 break;
415 }
416 }
417
418 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)
{
419 int errx = 0;
420 item = try_add_packet_field(L, tree_item, tvbr, hfid, type, encoding, &errx);
421 err = errx;
422 } CATCH_ALLif (except_state == 0 && exc != 0 && (except_state
|=1))
{
423 show_exception(tvbr->tvb->ws_tvb, lua_pinfo, tree_item->tree, EXCEPT_CODE((exc)->except_id.except_code), GET_MESSAGE((exc)->except_message));
424 error = "Lua programming error";
425 } ENDTRYif(!(except_state&1) && exc != 0) except_rethrow(
exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}
;
426
427 if (error) { WSLUA_ERROR(TreeItem_add_packet_field,error){ luaL_error(L, "%s%s", "TreeItem_add_packet_field" ": ", error
); }
; }
428
429 if (err != 0) {
430 lua_pushnil(L);
431 lua_pushnil(L);
432 }
433
434 while(nargs) {
435 const char* s;
436 s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
437 if (s) proto_item_append_text(item, " %s", s);
438 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
439 nargs--;
440 }
441
442 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
443
444 /* move the tree object before the field value */
445 lua_insert(L, 1)lua_rotate(L, (1), 1);
446
447 WSLUA_RETURN(3)return (3); /* The new child <<lua_class_TreeItem,`TreeItem`>>, the field's extracted value or nil, and offset or nil. */
448}
449
450/* The following is used by TreeItem_add() and TreeItem_le() and can THROW.
451 * It should be called inside a TRY (e.g. WRAP_NON_LUA_EXCEPTIONS) block and
452 * THROW_LUA_ERROR should be used insteadof lua[L]_error.
453 */
454static int TreeItem_add_item_any(lua_State *L, bool_Bool little_endian) {
455 TvbRange tvbr;
456 Proto proto;
457 ProtoField field;
458 int hfid = -1;
459 int ett = -1;
460 ftenum_t type = FT_NONE;
461 TreeItem tree_item = shiftTreeItem(L,1);
462 proto_item* item = NULL((void*)0);
463
464 if (!tree_item) {
465 THROW_LUA_ERROR("not a TreeItem!")except_throwf(1, (6), "not a TreeItem!");
466 }
467 if (tree_item->expired) {
468 THROW_LUA_ERROR("expired TreeItem")except_throwf(1, (6), "expired TreeItem");
469 return 0;
470 }
471
472 if (! ( field = shiftProtoField(L,1) ) ) {
473 if (( proto = shiftProto(L,1) )) {
474 hfid = proto->hfid;
475 type = FT_PROTOCOL;
476 ett = proto->ett;
477 } else if (lua_isnil(L, 1)(lua_type(L, (1)) == 0)) {
478 THROW_LUA_ERROR("first argument to TreeItem:add is nil!")except_throwf(1, (6), "first argument to TreeItem:add is nil!"
)
;
479 }
480 } else {
481 hfid = field->hfid;
482 type = field->type;
483 ett = field->ett;
484 }
485
486 tvbr = shiftTvbRange(L,1);
487
488 if (!tvbr) {
489 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
490 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb)((struct _wslua_tvb*)wmem_alloc((lua_pinfo->pool), sizeof(
struct _wslua_tvb)))
;
491 tvbr->tvb->ws_tvb = lua_tvb;
492 tvbr->offset = 0;
493 tvbr->len = 0;
494 }
495
496 if (hfid > 0 ) {
497 /* hfid is > 0 when the first arg was a ProtoField or Proto */
498
499 if (type == FT_STRINGZ) {
500 if (tvb_find_uint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
501 THROW_LUA_ERROR("out of bounds")except_throwf(1, (6), "out of bounds");
502 return 0;
503 }
504 tvbr->len = tvb_strsize (tvbr->tvb->ws_tvb, tvbr->offset);
505 }
506
507 if (lua_gettop(L)) {
508 /* if we got here, the (L,1) index is the value to add, instead of decoding from the Tvb */
509
510 /* It's invalid for it to be nil (which has been documented for
511 * a long time). Make sure we throw our error instead of an
512 * internal Lua error (due to nested setjmp/longjmp).
513 */
514 if (lua_isnil(L, 1)(lua_type(L, (1)) == 0)) {
515 THROW_LUA_ERROR("TreeItem:add value argument is nil!")except_throwf(1, (6), "TreeItem:add value argument is nil!");
516 }
517
518 switch(type) {
519 case FT_PROTOCOL:
520 item = proto_tree_add_item(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,ENC_NA0x00000000);
521 lua_pushinteger(L,0);
522 lua_insert(L,1)lua_rotate(L, (1), 1);
523 break;
524 case FT_BOOLEAN:
525 {
526 uint64_t val;
527 switch(lua_type(L, 1)) {
528
529 case LUA_TUSERDATA7:
530 val = checkUInt64(L, 1);
531 break;
532
533 default:
534 /* this needs to use checkinteger so that it can accept a Lua boolean and coerce it to an int */
535 val = (uint64_t) (wslua_tointeger(L,1));
536 }
537 item = proto_tree_add_boolean(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,val);
538 }
539 break;
540 case FT_CHAR:
541 case FT_UINT8:
542 case FT_UINT16:
543 case FT_UINT24:
544 case FT_UINT32:
545 case FT_FRAMENUM:
546 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) ));
547 break;
548 case FT_INT8:
549 case FT_INT16:
550 case FT_INT24:
551 case FT_INT32:
552 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) ));
553 break;
554 case FT_FLOAT:
555 item = proto_tree_add_float(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(float)luaL_checknumber(L,1));
556 break;
557 case FT_DOUBLE:
558 item = proto_tree_add_double(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,(double)luaL_checknumber(L,1));
559 break;
560 case FT_ABSOLUTE_TIME:
561 case FT_RELATIVE_TIME:
562 item = proto_tree_add_time(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkNSTime(L,1));
563 break;
564 case FT_STRING:
565 case FT_STRINGZ:
566 item = proto_tree_add_string(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,luaL_checkstring(L,1)(luaL_checklstring(L, (1), ((void*)0))));
567 break;
568 case FT_BYTES:
569 item = proto_tree_add_bytes(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len, (const uint8_t*) luaL_checkstring(L,1)(luaL_checklstring(L, (1), ((void*)0))));
570 break;
571 case FT_UINT64:
572 item = proto_tree_add_uint64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkUInt64(L,1));
573 break;
574 case FT_INT64:
575 item = proto_tree_add_int64(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,checkInt64(L,1));
576 break;
577 case FT_IPv4:
578 {
579 Address addr = checkAddress(L,1);
580 uint32_t addr_value;
581
582 if (addr->type != AT_IPv4) {
583 THROW_LUA_ERROR("Expected IPv4 address for FT_IPv4 field")except_throwf(1, (6), "Expected IPv4 address for FT_IPv4 field"
)
;
584 return 0;
585 }
586
587 /*
588 * The address is not guaranteed to be aligned on a
589 * 32-bit boundary, so we can't safely dereference
590 * the pointer as if it were so aligned.
591 */
592 memcpy(&addr_value, addr->data, sizeof addr_value);
593 item = proto_tree_add_ipv4(tree_item->tree,hfid,tvbr->tvb->ws_tvb,tvbr->offset,tvbr->len,addr_value);
594 }
595 break;
596 case FT_IPv6:
597 {
598 Address addr = checkAddress(L,1);
599 if (addr->type != AT_IPv6) {
600 THROW_LUA_ERROR("Expected IPv6 address for FT_IPv6 field")except_throwf(1, (6), "Expected IPv6 address for FT_IPv6 field"
)
;
601 return 0;
602 }
603
604 item = proto_tree_add_ipv6(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, (const ws_in6_addr *)addr->data);
605 }
606 break;
607 case FT_ETHER:
608 {
609 Address addr = checkAddress(L,1);
610 if (addr->type != AT_ETHER) {
611 THROW_LUA_ERROR("Expected MAC address for FT_ETHER field")except_throwf(1, (6), "Expected MAC address for FT_ETHER field"
)
;
612 return 0;
613 }
614
615 item = proto_tree_add_ether(tree_item->tree, hfid, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, (const uint8_t *)addr->data);
616 }
617 break;
618 case FT_UINT_BYTES:
619 case FT_IPXNET:
620 case FT_GUID:
621 case FT_OID:
622 case FT_REL_OID:
623 case FT_SYSTEM_ID:
624 case FT_VINES:
625 case FT_FCWWN:
626 default:
627 THROW_LUA_ERROR("%s not yet supported", ftype_name(type))except_throwf(1, (6), "%s not yet supported", ftype_name(type
))
;
628 return 0;
629 }
630
631 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
632
633 } else {
634 if (type == FT_FRAMENUM) {
635 THROW_LUA_ERROR("ProtoField FRAMENUM cannot fetch value from Tvb")except_throwf(1, (6), "ProtoField FRAMENUM cannot fetch value from Tvb"
)
;
636 return 0;
637 }
638 /* the Lua stack is empty - no value was given - so decode the value from the tvb */
639 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);
640 }
641
642 if ( lua_gettop(L) ) {
643 /* if there was a value, it was removed earlier, so what's left is the display string to set */
644 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
645 if (s) proto_item_set_text(item,"%s",s);
646 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
647 }
648
649 } else {
650 /* no ProtoField or Proto was given - we're adding a text-only field,
651 * any remaining parameters are parts of the text label. */
652 if (lua_gettop(L)) {
653 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
654 const int hf = get_hf_wslua_text();
655 if (hf > -1) {
656 /* use proto_tree_add_none_format() instead? */
657 item = proto_tree_add_item(tree_item->tree, hf, tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len, ENC_NA0x00000000);
658 proto_item_set_text(item, "%s", s);
659 } else {
660 THROW_LUA_ERROR("Internal error: hf_wslua_text not registered")except_throwf(1, (6), "Internal error: hf_wslua_text not registered"
)
;
661 }
662 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
663 } else {
664 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?)"
)
;
665 }
666 }
667
668 while(lua_gettop(L)) {
669 /* keep appending more text */
670 const char* s = lua_tostring(L,1)lua_tolstring(L, (1), ((void*)0));
671 if (s) proto_item_append_text(item, " %s", s);
672 lua_remove(L,1)(lua_rotate(L, (1), -1), lua_settop(L, -(1)-1));
673 }
674
675 push_TreeItem(L, proto_item_add_subtree(item,ett > 0 ? ett : wslua_ett), item);
676
677 return 1;
678}
679
680
681WSLUA_METHODstatic int TreeItem_add(lua_State *L) {
682 /*
683 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
684
685 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.
686
687 This function has a complicated form: 'treeitem:add([protofield,] [tvbrange,] [[value], label]])', such that if the first
688 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;
689 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',
690 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
691 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
692
693 [discrete]
694 ====== Example
695
696 [source,lua]
697 ----
698 local proto_foo = Proto("foo", "Foo Protocol")
699 proto_foo.fields.bytes = ProtoField.bytes("foo.bytes", "Byte array")
700 proto_foo.fields.u16 = ProtoField.uint16("foo.u16", "Unsigned short", base.HEX)
701
702 function proto_foo.dissector(buf, pinfo, tree)
703 -- ignore packets less than 4 bytes long
704 if buf:len() < 4 then return end
705
706 -- ##############################################
707 -- # Assume buf(0,4) == {0x00, 0x01, 0x00, 0x02}
708 -- ##############################################
709
710 local t = tree:add( proto_foo, buf() )
711
712 -- Adds a byte array that shows as: "Byte array: 00010002"
713 t:add( proto_foo.fields.bytes, buf(0,4) )
714
715 -- Adds a byte array that shows as "Byte array: 313233"
716 -- (the ASCII char code of each character in "123")
717 t:add( proto_foo.fields.bytes, buf(0,4), "123" )
718
719 -- Adds a tree item that shows as: "Unsigned short: 0x0001"
720 t:add( proto_foo.fields.u16, buf(0,2) )
721
722 -- Adds a tree item that shows as: "Unsigned short: 0x0064"
723 t:add( proto_foo.fields.u16, buf(0,2), 100 )
724
725 -- Adds a tree item that shows as: "Unsigned short: 0x0064 ( big endian )"
726 t:add( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "big", 999, nil, "endian", nil, ")" )
727
728 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x0100"
729 t:add_le( proto_foo.fields.u16, buf(0,2) )
730
731 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400"
732 t:add_le( proto_foo.fields.u16, buf(0,2), 100 )
733
734 -- LITTLE ENDIAN: Adds a tree item that shows as: "Unsigned short: 0x6400 ( little endian )"
735 t:add_le( proto_foo.fields.u16, buf(1,2), 100, nil, "(", nil, "little", 999, nil, "endian", nil, ")" )
736 end
737
738 udp_table = DissectorTable.get("udp.port")
739 udp_table:add(7777, proto_foo)
740 ----
741 */
742#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. */
743#define WSLUA_OPTARG_TreeItem_add_TVBRANGE3 3 /* The <<lua_class_TvbRange,`TvbRange`>> of bytes in the packet this tree item covers/represents. */
744#define WSLUA_OPTARG_TreeItem_add_VALUE4 4 /* The field's value, instead of the ProtoField/Proto one. */
745#define WSLUA_OPTARG_TreeItem_add_LABEL5 5 /* One or more strings to use for the tree item label, instead of the ProtoField/Proto one. */
746
747 volatile int ret;
1
'ret' declared without an initial value
748 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
749 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); } }
750 ){ 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); } }
751 WSLUA_RETURN(ret)return (ret); /* The new child TreeItem. */
9
Undefined or garbage value returned to caller
752}
753
754WSLUA_METHODstatic int TreeItem_add_le(lua_State *L) {
755 /*
756 Adds a child item to this tree item, returning the new child <<lua_class_TreeItem,`TreeItem`>>.
757
758 If the <<lua_class_ProtoField,`ProtoField`>> represents a numeric value (int, uint or float), then it's treated as a Little Endian value.
759
760 This function has a complicated form: 'treeitem:add_le([protofield,] [tvbrange,] [[value], label]])', such that if the first
761 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;
762 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',
763 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
764 be either a <<lua_class_TvbRange,`TvbRange`>> or a label, and the value is not in use.
765 */
766#define WSLUA_OPTARG_TreeItem_add_le_PROTOFIELD2 2 /* The ProtoField field or Proto protocol object to add to the tree. */
767#define WSLUA_OPTARG_TreeItem_add_le_TVBRANGE3 3 /* The TvbRange of bytes in the packet this tree item covers/represents. */
768#define WSLUA_OPTARG_TreeItem_add_le_VALUE4 4 /* The field's value, instead of the ProtoField/Proto one. */
769#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. */
770 volatile int ret;
771 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); } }
772 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); } }
773 ){ 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); } }
774 WSLUA_RETURN(ret)return (ret); /* The new child TreeItem. */
775}
776
777/* WSLUA_ATTRIBUTE TreeItem_text RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s display string (string).
778
779 For the getter, if the TreeItem has no display string, then nil is returned.
780 */
781static int TreeItem_get_text(lua_State* L) {
782 TreeItem ti = checkTreeItem(L,1);
783 char label_str[ITEM_LABEL_LENGTH240+1];
784 char *label_ptr;
785
786 if (ti->item && PITEM_FINFO(ti->item)((ti->item)->finfo)) {
787 field_info *fi = PITEM_FINFO(ti->item)((ti->item)->finfo);
788
789 if (!fi->rep) {
790 label_ptr = label_str;
791 proto_item_fill_label(fi, label_str, NULL((void*)0));
792 } else
793 label_ptr = fi->rep->representation;
794
795 if (label_ptr) {
796 lua_pushstring(L, label_ptr);
797 } else {
798 lua_pushnil(L);
799 }
800 } else {
801 lua_pushnil(L);
802 }
803
804 return 1;
805}
806
807/* the following is used as both a method and attribute */
808WSLUA_METHODstatic int TreeItem_set_text(lua_State *L) {
809 /* Sets the text of the label.
810
811 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
812 */
813#define WSLUA_ARG_TreeItem_set_text_TEXT2 2 /* The text to be used. */
814 TreeItem ti = checkTreeItem(L,1);
815 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_set_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
816
817 proto_item_set_text(ti->item,"%s",s);
818
819 /* copy the TreeItem userdata so we give it back */
820 lua_pushvalue(L, 1);
821
822 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
823}
824
825WSLUA_METHODstatic int TreeItem_append_text(lua_State *L) {
826 /* Appends text to the label.
827
828 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
829 */
830#define WSLUA_ARG_TreeItem_append_text_TEXT2 2 /* The text to be appended. */
831 TreeItem ti = checkTreeItem(L,1);
832 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_append_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
833
834 proto_item_append_text(ti->item,"%s",s);
835
836 /* copy the TreeItem userdata so we give it back */
837 lua_pushvalue(L, 1);
838
839 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
840}
841
842WSLUA_METHODstatic int TreeItem_prepend_text(lua_State *L) {
843 /* Prepends text to the label.
844
845 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
846 */
847#define WSLUA_ARG_TreeItem_prepend_text_TEXT2 2 /* The text to be prepended. */
848 TreeItem ti = checkTreeItem(L,1);
849 const char* s = luaL_checkstring(L,WSLUA_ARG_TreeItem_prepend_text_TEXT)(luaL_checklstring(L, (2), ((void*)0)));
850
851 proto_item_prepend_text(ti->item,"%s",s);
852
853 /* copy the TreeItem userdata so we give it back */
854 lua_pushvalue(L, 1);
855
856 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
857}
858
859WSLUA_METHODstatic int TreeItem_add_expert_info(lua_State *L) {
860 /* Sets the expert flags of the item and adds expert info to the packet.
861
862 This function does *not* create a truly filterable expert info for a protocol.
863 Instead you should use `TreeItem.add_proto_expert_info()`.
864
865 Note: This function is provided for backwards compatibility only, and should not
866 be used in new Lua code. It may be removed in the future. You should only
867 use `TreeItem.add_proto_expert_info()`.
868 */
869#define WSLUA_OPTARG_TreeItem_add_expert_info_GROUP2 2 /* One of:
870 `PI_CHECKSUM`,
871 `PI_SEQUENCE`,
872 `PI_RESPONSE_CODE`,
873 `PI_REQUEST_CODE`,
874 `PI_UNDECODED`,
875 `PI_REASSEMBLE`,
876 `PI_MALFORMED`,
877 `PI_DEBUG`,
878 `PI_PROTOCOL`,
879 `PI_SECURITY`,
880 `PI_COMMENTS_GROUP`,
881 `PI_DECRYPTION`,
882 `PI_ASSUMPTION`,
883 `PI_DEPRECATED`,
884 `PI_RECEIVE`,
885 `PI_INTERFACE`,
886 or `PI_DISSECTOR_BUG`. */
887#define WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY3 3 /* One of:
888 `PI_COMMENT`,
889 `PI_CHAT`,
890 `PI_NOTE`,
891 `PI_WARN`,
892 or `PI_ERROR`. */
893#define WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4 4 /* The text for the expert info display. */
894 TreeItem ti = checkTreeItem(L,1);
895 int group = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_GROUP2,PI_DEBUG0x08000000);
896 int severity = (int)luaL_optinteger(L,WSLUA_OPTARG_TreeItem_add_expert_info_SEVERITY3,PI_CHAT0x00200000);
897 expert_field* ei_info = wslua_get_expert_field(group, severity);
898 const char* str;
899
900 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4) {
901 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_expert_info_TEXT4);
902 expert_add_info_format(lua_pinfo, ti->item, ei_info, "%s", str);
903 } else {
904 expert_add_info(lua_pinfo, ti->item, ei_info);
905 }
906
907 /* copy the TreeItem userdata so we give it back */
908 lua_pushvalue(L, 1);
909
910 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
911}
912
913WSLUA_METHODstatic int TreeItem_add_proto_expert_info(lua_State *L) {
914 /* Sets the expert flags of the tree item and adds expert info to the packet. */
915#define WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
916#define WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3 3 /* Text for the expert info display
917 (default is to use the registered
918 text). */
919 TreeItem ti = checkTreeItem(L,1);
920 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2);
921 const char* str;
922
923 if (expert->ids.ei == EI_INIT_EI-1 || expert->ids.hf == EI_INIT_HF-1) {
924 luaL_error(L, "ProtoExpert is not registered");
925 return 0;
926 }
927
928 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3) {
929 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3);
930 expert_add_info_format(lua_pinfo, ti->item, &expert->ids, "%s", str);
931 } else {
932 expert_add_info(lua_pinfo, ti->item, &expert->ids);
933 }
934
935 /* copy the TreeItem userdata so we give it back */
936 lua_pushvalue(L, 1);
937
938 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
939}
940
941WSLUA_METHODstatic int TreeItem_add_tvb_expert_info(lua_State *L) {
942 /* Sets the expert flags of the tree item and adds expert info to the packet
943 associated with the <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> bytes in the packet. */
944#define WSLUA_ARG_TreeItem_add_tvb_expert_info_EXPERT2 2 /* The <<lua_class_ProtoExpert,`ProtoExpert`>> object to add to the tree. */
945#define WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3 3 /* The <<lua_class_Tvb,`Tvb`>> or <<lua_class_TvbRange,`TvbRange`>> object bytes to associate
946 the expert info with. */
947#define WSLUA_OPTARG_TreeItem_add_tvb_expert_info_TEXT4 4 /* Text for the expert info display
948 (default is to use the registered
949 text). */
950 TreeItem ti = checkTreeItem(L,1);
951 ProtoExpert expert = checkProtoExpert(L,WSLUA_ARG_TreeItem_add_proto_expert_info_EXPERT2);
952 TvbRange tvbr;
953 const char* str;
954
955 if (expert->ids.ei == EI_INIT_EI-1 || expert->ids.hf == EI_INIT_HF-1) {
956 luaL_error(L, "ProtoExpert is not registered");
957 return 0;
958 }
959
960 tvbr = shiftTvbRange(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3);
961
962 if (!tvbr) {
963 tvbr = wmem_new(lua_pinfo->pool, struct _wslua_tvbrange)((struct _wslua_tvbrange*)wmem_alloc((lua_pinfo->pool), sizeof
(struct _wslua_tvbrange)))
;
964 tvbr->tvb = shiftTvb(L,WSLUA_ARG_TreeItem_add_tvb_expert_info_TVB3);
965 if (!tvbr->tvb) {
966 tvbr->tvb = wmem_new(lua_pinfo->pool, struct _wslua_tvb)((struct _wslua_tvb*)wmem_alloc((lua_pinfo->pool), sizeof(
struct _wslua_tvb)))
;
967 }
968 tvbr->tvb->ws_tvb = lua_tvb;
969 tvbr->offset = 0;
970 tvbr->len = 0;
971 }
972
973 if (lua_gettop(L) >= WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3) {
974 str = wslua_checkstring_only(L, WSLUA_OPTARG_TreeItem_add_proto_expert_info_TEXT3);
975 proto_tree_add_expert_format(ti->tree, lua_pinfo, &expert->ids,
976 tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len,
977 "%s", str);
978 } else {
979 proto_tree_add_expert(ti->tree, lua_pinfo, &expert->ids,
980 tvbr->tvb->ws_tvb, tvbr->offset, tvbr->len);
981 }
982
983 /* copy the TreeItem userdata so we give it back */
984 lua_pushvalue(L, 1);
985
986 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
987}
988
989
990/* WSLUA_ATTRIBUTE TreeItem_visible RO Get the <<lua_class_TreeItem,`TreeItem`>>'s subtree visibility status (boolean). */
991static int TreeItem_get_visible(lua_State* L) {
992 TreeItem ti = checkTreeItem(L,1);
993
994 if (ti->tree) {
995 lua_pushboolean(L, PTREE_DATA(ti->tree)((ti->tree)->tree_data)->visible);
996 }
997 else {
998 lua_pushboolean(L, false0);
999 }
1000
1001 return 1;
1002}
1003
1004
1005/* WSLUA_ATTRIBUTE TreeItem_generated RW Set/get the <<lua_class_TreeItem,`TreeItem`>>'s generated state (boolean). */
1006static int TreeItem_get_generated(lua_State* L) {
1007 TreeItem ti = checkTreeItem(L,1);
1008
1009 lua_pushboolean(L, proto_item_is_generated(ti->item));
1010
1011 return 1;
1012}
1013
1014/* the following is used as both a method and attribute. As a method it defaults
1015 to setting the value, because that's what it used to do before. */
1016WSLUA_METHODstatic int TreeItem_set_generated(lua_State *L) {
1017 /* Marks the <<lua_class_TreeItem,`TreeItem`>> as a generated field (with data inferred but not contained in the packet).
1018
1019 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1020 */
1021#define WSLUA_OPTARG_TreeItem_set_generated_BOOL2 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1022 generated flag, else clears it (default=true) */
1023 TreeItem ti = checkTreeItem(L,1);
1024 bool_Bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_generated_BOOL2, true1);
1025
1026 if (set) {
1027 proto_item_set_generated(ti->item);
1028 } else {
1029 if (ti->item)
1030 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)
;
1031 }
1032
1033 /* copy the TreeItem userdata so we give it back */
1034 lua_pushvalue(L, 1);
1035
1036 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1037}
1038
1039/* WSLUA_ATTRIBUTE TreeItem_hidden RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s hidden state (boolean). */
1040static int TreeItem_get_hidden(lua_State* L) {
1041 TreeItem ti = checkTreeItem(L,1);
1042
1043 lua_pushboolean(L, proto_item_is_hidden(ti->item));
1044
1045 return 1;
1046}
1047
1048/* the following is used as both a method and attribute. As a method it defaults
1049 to setting the value, because that's what it used to do before. */
1050WSLUA_METHODstatic int TreeItem_set_hidden(lua_State *L) {
1051 /*
1052 Marks the <<lua_class_TreeItem,`TreeItem`>> as a hidden field (neither displayed nor used in filters).
1053 Deprecated
1054
1055 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1056 */
1057#define WSLUA_OPTARG_TreeItem_set_hidden_BOOL2 2 /* A Lua boolean, which if `true` sets the <<lua_class_TreeItem,`TreeItem`>>
1058 hidden flag, else clears it. Default is `true`. */
1059 TreeItem ti = checkTreeItem(L,1);
1060 bool_Bool set = wslua_optbool(L, WSLUA_OPTARG_TreeItem_set_hidden_BOOL2, true1);
1061
1062 if (set) {
1063 proto_item_set_hidden(ti->item);
1064 } else {
1065 proto_item_set_visible(ti->item);
1066 }
1067
1068 /* copy the TreeItem userdata so we give it back */
1069 lua_pushvalue(L, 1);
1070
1071 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1072}
1073
1074/* WSLUA_ATTRIBUTE TreeItem_len RW Set/get <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created. */
1075static int TreeItem_get_len(lua_State* L) {
1076 TreeItem ti = checkTreeItem(L,1);
1077 int len = 0;
1078
1079 /* XXX - this is *NOT* guaranteed to return a correct value! */
1080 len = proto_item_get_len(ti->item);
1081
1082 lua_pushinteger(L, len > 0 ? len : 0);
1083
1084 return 1;
1085}
1086
1087WSLUA_METHODstatic int TreeItem_set_len(lua_State *L) {
1088 /* Set <<lua_class_TreeItem,`TreeItem`>>'s length inside tvb, after it has already been created.
1089
1090 This used to return nothing, but as of 1.11.3 it returns the same tree item to allow chained calls.
1091 */
1092#define WSLUA_ARG_TreeItem_set_len_LEN2 2 /* The length to be used. */
1093 TreeItem ti = checkTreeItem(L,1);
1094 int len = (int)luaL_checkinteger(L,WSLUA_ARG_TreeItem_set_len_LEN2);
1095
1096 proto_item_set_len(ti->item, len);
1097
1098 /* copy the TreeItem userdata so we give it back */
1099 lua_pushvalue(L, 1);
1100
1101 WSLUA_RETURN(1)return (1); /* The same TreeItem. */
1102}
1103
1104WSLUA_METHODstatic int TreeItem_referenced(lua_State *L) {
1105 /* Checks if a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> is referenced by a filter/tap/UI.
1106
1107 If this function returns `false`, it means that the field (or dissector) does not need to be dissected
1108 and can be safely skipped. By skipping a field rather than dissecting it, the dissector will
1109 usually run faster since Wireshark will not do extra dissection work when it doesn't need the field.
1110
1111 You can use this in conjunction with the TreeItem.visible attribute. This function will always return
1112 true when the TreeItem is visible. When it is not visible and the field is not referenced, you can
1113 speed up the dissection by not dissecting the field as it is not needed for display or filtering.
1114
1115 This function takes one parameter that can be a <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>>.
1116 The <<lua_class_Dissector,`Dissector`>> form is useful when you need to decide whether to call a sub-dissector.
1117 */
1118#define WSLUA_ARG_TreeItem_referenced_PROTOFIELD2 2 /* The <<lua_class_ProtoField,`ProtoField`>> or <<lua_class_Dissector,`Dissector`>> to check if referenced. */
1119 TreeItem ti = checkTreeItem(L, 1);
1120 if (!ti) return 0;
1121 ProtoField f = shiftProtoField(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD2);
1122 if (f) {
1123 lua_pushboolean(L, proto_field_is_referenced(ti->tree, f->hfid));
1124 }
1125 else {
1126 Dissector d = checkDissector(L, WSLUA_ARG_TreeItem_referenced_PROTOFIELD2);
1127 if (!d) return 0;
1128 lua_pushboolean(L, proto_field_is_referenced(ti->tree, dissector_handle_get_protocol_index(d)));
1129 }
1130 WSLUA_RETURN(1)return (1); /* A boolean indicating if the ProtoField/Dissector is referenced */
1131}
1132
1133WSLUA_METAMETHODstatic int TreeItem__tostring(lua_State* L) {
1134 /* Returns string debug information about the <<lua_class_TreeItem,`TreeItem`>>. */
1135 TreeItem ti = toTreeItem(L,1);
1136
1137 if (ti) {
1138 lua_pushfstring(L,
1139 "TreeItem: expired=%s, has item=%s, has subtree=%s, they are %sthe same",
1140 ti->expired ? "true" : "false",
1141 ti->item ? "true" : "false",
1142 ti->tree ? "true" : "false",
1143 (ti->tree == ti->item) ? "" : "not ");
1144 }
1145 else {
1146 lua_pushstring(L, "No TreeItem object!");
1147 }
1148
1149 return 1;
1150}
1151
1152/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
1153static int TreeItem__gc(lua_State* L) {
1154 TreeItem ti = toTreeItem(L,1);
1155 if (!ti) return 0;
1156 if (!ti->expired)
1157 ti->expired = true1;
1158 else
1159 g_free(ti);
1160 return 0;
1161}
1162
1163WSLUA_ATTRIBUTESstatic const wslua_attribute_table TreeItem_attributes[] = {
1164 WSLUA_ATTRIBUTE_RWREG(TreeItem,generated){ "generated", TreeItem_get_generated, TreeItem_set_generated
}
,
1165 WSLUA_ATTRIBUTE_RWREG(TreeItem,hidden){ "hidden", TreeItem_get_hidden, TreeItem_set_hidden },
1166 WSLUA_ATTRIBUTE_RWREG(TreeItem,len){ "len", TreeItem_get_len, TreeItem_set_len },
1167 WSLUA_ATTRIBUTE_RWREG(TreeItem,text){ "text", TreeItem_get_text, TreeItem_set_text },
1168 WSLUA_ATTRIBUTE_ROREG(TreeItem,visible){ "visible", TreeItem_get_visible, ((void*)0) },
1169 { NULL((void*)0), NULL((void*)0), NULL((void*)0) }
1170};
1171
1172WSLUA_METHODSstatic const luaL_Reg TreeItem_methods[] = {
1173 WSLUA_CLASS_FNREG(TreeItem,add_packet_field){ "add_packet_field", TreeItem_add_packet_field },
1174 WSLUA_CLASS_FNREG(TreeItem,add){ "add", TreeItem_add },
1175 WSLUA_CLASS_FNREG(TreeItem,add_le){ "add_le", TreeItem_add_le },
1176 WSLUA_CLASS_FNREG(TreeItem,set_text){ "set_text", TreeItem_set_text },
1177 WSLUA_CLASS_FNREG(TreeItem,append_text){ "append_text", TreeItem_append_text },
1178 WSLUA_CLASS_FNREG(TreeItem,prepend_text){ "prepend_text", TreeItem_prepend_text },
1179 WSLUA_CLASS_FNREG(TreeItem,add_expert_info){ "add_expert_info", TreeItem_add_expert_info },
1180 WSLUA_CLASS_FNREG(TreeItem,add_proto_expert_info){ "add_proto_expert_info", TreeItem_add_proto_expert_info },
1181 WSLUA_CLASS_FNREG(TreeItem,add_tvb_expert_info){ "add_tvb_expert_info", TreeItem_add_tvb_expert_info },
1182 WSLUA_CLASS_FNREG(TreeItem,set_generated){ "set_generated", TreeItem_set_generated },
1183 WSLUA_CLASS_FNREG(TreeItem,set_hidden){ "set_hidden", TreeItem_set_hidden },
1184 WSLUA_CLASS_FNREG(TreeItem,set_len){ "set_len", TreeItem_set_len },
1185 WSLUA_CLASS_FNREG(TreeItem,referenced){ "referenced", TreeItem_referenced },
1186 { NULL((void*)0), NULL((void*)0) }
1187};
1188
1189WSLUA_METAstatic const luaL_Reg TreeItem_meta[] = {
1190 WSLUA_CLASS_MTREG(TreeItem,tostring){ "__" "tostring", TreeItem__tostring },
1191 { NULL((void*)0), NULL((void*)0) }
1192};
1193
1194int TreeItem_register(lua_State *L) {
1195 int* etts[] = { &wslua_ett };
1196 wslua_ett = -1; /* Reset to support reload Lua plugins */
1197 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, (-1000000 - 1000), ("TreeItem"))); lua_pushcclosure
(L, (TreeItem__gc), 0); lua_setfield(L, -2, "__gc"); lua_settop
(L, -(1)-1); }
;
1198 if (outstanding_TreeItem != NULL((void*)0)) {
1199 g_ptr_array_unref(outstanding_TreeItem);
1200 }
1201 outstanding_TreeItem = g_ptr_array_new();
1202 proto_register_subtree_array(etts,1);
1203 return 0;
1204}
1205
1206/*
1207 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1208 *
1209 * Local variables:
1210 * c-basic-offset: 4
1211 * tab-width: 8
1212 * indent-tabs-mode: nil
1213 * End:
1214 *
1215 * vi: set shiftwidth=4 tabstop=8 expandtab:
1216 * :indentSize=4:tabSize=8:noTabs=true:
1217 */