2 -- This is a test script for tshark/wireshark.
3 -- This script runs inside tshark/wireshark, so to run it do:
4 -- wireshark -X lua_script:<path_to_testdir>/lua/struct.lua
5 -- tshark -r bogus.cap -X lua_script:<path_to_testdir>/lua/struct.lua
7 -- Tests Struct functions
9 local testlib
= require("testlib")
13 -- auxiliary function to print an hexadecimal `dump' of a given string
14 -- (not used by the test)
16 local function tohex(s
, sep
)
17 local patt
= "%02x" .. (sep
or "")
18 s
= string.gsub(s
, "(.)", function(c
)
19 return string.format(patt
, string.byte(c
))
21 if sep
then s
= s
:sub(1,-(sep
:len()+1)) end
31 -----------------------------
33 print("Lua version: ".._VERSION
)
35 testlib
.init({ [OTHER
] = 0 })
37 testlib
.testing(OTHER
, "Struct library")
40 testlib
.test(OTHER
,"global",_G
.Struct
== lib
)
42 for name
, val
in pairs(lib
) do
43 print("\t"..name
.." = "..type(val
))
46 testlib
.test(OTHER
,"class1",type(lib
) == 'table')
47 testlib
.test(OTHER
,"class2",type(lib
.pack
) == 'function')
48 testlib
.test(OTHER
,"class3",type(lib
.unpack
) == 'function')
49 testlib
.test(OTHER
,"class4",type(lib
.size
) == 'function')
52 local val1
= "\42\00\00\00\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00\04"
53 local fmt1_le
= "<!4biii4i4"
54 local fmt1_be
= ">!4biii4i4"
55 local fmt1_64le
= "<!4ieE"
56 local fmt1_64be
= ">!4ieE"
57 local fmt2_be
= ">!4bi(ii4)i"
59 testlib
.testing(OTHER
, "basic size")
61 testlib
.test(OTHER
,"basic_size1", lib
.size(fmt1_le
) == string.len(val1
))
62 testlib
.test(OTHER
,"basic_size2", lib
.size(fmt1_le
) == Struct
.size(fmt1_be
))
63 testlib
.test(OTHER
,"basic_size3", lib
.size(fmt1_le
) == Struct
.size(fmt1_64le
))
64 testlib
.test(OTHER
,"basic_size4", lib
.size(fmt2_be
) == Struct
.size(fmt1_64le
))
66 testlib
.testing(OTHER
, "basic values")
68 testlib
.test(OTHER
,"basic_values1", lib
.values(fmt1_le
) == 5)
69 testlib
.test(OTHER
,"basic_values2", lib
.values(fmt1_be
) == lib
.values(fmt1_le
))
70 testlib
.test(OTHER
,"basic_values3", lib
.values(fmt1_64le
) == 3)
71 testlib
.test(OTHER
,"basic_values4", lib
.values(fmt2_be
) == lib
.values(fmt1_64le
))
72 testlib
.test(OTHER
,"basic_values4", lib
.values(" (I) s x i XxX c0") == 3)
74 testlib
.testing(OTHER
, "tohex")
75 local val1hex
= "2A:00:00:00:00:00:00:01:00:00:00:02:00:00:00:03:00:00:00:04"
76 testlib
.test(OTHER
,"tohex1", Struct
.tohex(val1
) == tohex(val1
):upper())
77 testlib
.test(OTHER
,"tohex2", Struct
.tohex(val1
,true) == tohex(val1
))
78 testlib
.test(OTHER
,"tohex3", Struct
.tohex(val1
,false,":") == val1hex
)
79 testlib
.test(OTHER
,"tohex4", Struct
.tohex(val1
,true,":") == val1hex
:lower())
81 testlib
.testing(OTHER
, "fromhex")
82 testlib
.test(OTHER
,"fromhex1", Struct
.fromhex(val1hex
,":") == val1
)
83 local val1hex2
= val1hex
:gsub(":","")
84 testlib
.test(OTHER
,"fromhex2", Struct
.fromhex(val1hex2
) == val1
)
85 testlib
.test(OTHER
,"fromhex3", Struct
.fromhex(val1hex2
:lower()) == val1
)
87 testlib
.testing(OTHER
, "basic unpack")
88 local ret1
, ret2
, ret3
, ret4
, ret5
, pos
= lib
.unpack(fmt1_le
, val1
)
89 testlib
.test(OTHER
,"basic_unpack1", ret1
== 42 and ret2
== 0x01000000 and ret3
== 0x02000000 and ret4
== 0x03000000 and ret5
== 0x04000000)
90 testlib
.test(OTHER
,"basic_unpack_position1", pos
== string.len(val1
) + 1)
92 ret1
, ret2
, ret3
, ret4
, ret5
, pos
= lib
.unpack(fmt1_be
, val1
)
93 testlib
.test(OTHER
,"basic_unpack2", ret1
== 42 and ret2
== 1 and ret3
== 2 and ret4
== 3 and ret5
== 4)
94 testlib
.test(OTHER
,"basic_unpack_position2", pos
== string.len(val1
) + 1)
96 ret1
, ret2
, ret3
, pos
= lib
.unpack(fmt1_64le
, val1
)
97 testlib
.test(OTHER
,"basic_unpack3", ret1
== 42 and ret2
== Int64
.new( 0x01000000, 0x02000000) and ret3
== UInt64
.new( 0x03000000, 0x04000000))
98 print(typeof(ret2
),typeof(ret3
))
99 testlib
.test(OTHER
,"basic_unpack3b", typeof(ret2
) == "Int64" and typeof(ret3
) == "UInt64")
100 testlib
.test(OTHER
,"basic_unpack_position3", pos
== string.len(val1
) + 1)
102 ret1
, ret2
, ret3
, pos
= lib
.unpack(fmt1_64be
, val1
)
103 testlib
.test(OTHER
,"basic_unpack4", ret1
== 0x2A000000 and ret2
== Int64
.new( 2, 1) and ret3
== UInt64
.new( 4, 3))
104 testlib
.test(OTHER
,"basic_unpack4b", typeof(ret2
) == "Int64" and typeof(ret3
) == "UInt64")
105 testlib
.test(OTHER
,"basic_unpack_position4", pos
== string.len(val1
) + 1)
107 ret1
, ret2
, ret3
, pos
= lib
.unpack(fmt2_be
, val1
)
108 testlib
.test(OTHER
,"basic_unpack5", ret1
== 42 and ret2
== 1 and ret3
== 4)
109 testlib
.test(OTHER
,"basic_unpack_position5", pos
== string.len(val1
) + 1)
111 testlib
.testing(OTHER
, "basic pack")
112 local pval1
= lib
.pack(fmt1_le
, lib
.unpack(fmt1_le
, val1
))
113 testlib
.test(OTHER
,"basic_pack1", pval1
== val1
)
114 testlib
.test(OTHER
,"basic_pack2", val1
== lib
.pack(fmt1_be
, lib
.unpack(fmt1_be
, val1
)))
115 testlib
.test(OTHER
,"basic_pack3", val1
== lib
.pack(fmt1_64le
, lib
.unpack(fmt1_64le
, val1
)))
116 testlib
.test(OTHER
,"basic_pack4", val1
== lib
.pack(fmt1_64be
, lib
.unpack(fmt1_64be
, val1
)))
117 testlib
.test(OTHER
,"basic_pack5", lib
.pack(fmt2_be
, lib
.unpack(fmt1_be
, val1
)) == lib
.pack(">!4biiii", 42, 1, 0, 0, 2))
119 ----------------------------------
120 -- following comes from:
121 -- https://github.com/LuaDist/struct/blob/master/teststruct.lua
122 -- unfortunately many of his tests assumed a local machine word
123 -- size of 4 bytes for long and such, so I had to muck with this
124 -- to make it handle 64-bit compiles.
125 -- $Id: teststruct.lua,v 1.2 2008/04/18 20:06:01 roberto Exp $
128 -- some pack/unpack commands are host-size dependent, so we need to pad
129 local l_pad
, ln_pad
= "",""
130 if lib
.size("l") == 8 then
131 -- the machine running this script uses a long of 8 bytes
132 l_pad
= "\00\00\00\00"
133 ln_pad
= "\255\255\255\255"
138 testlib
.testing(OTHER
, "pack")
139 testlib
.test(OTHER
,"pack_I",#Struct
.pack("I", 67324752) == 4)
141 testlib
.test(OTHER
,"pack_b1",lib
.pack('b', 10) == string.char(10))
142 testlib
.test(OTHER
,"pack_b2",lib
.pack('bbb', 10, 20, 30) == string.char(10, 20, 30))
144 testlib
.test(OTHER
,"pack_h1",lib
.pack('<h', 10) == string.char(10, 0))
145 testlib
.test(OTHER
,"pack_h2",lib
.pack('>h', 10) == string.char(0, 10))
146 testlib
.test(OTHER
,"pack_h3",lib
.pack('<h', -10) == string.char(256-10, 256-1))
148 testlib
.test(OTHER
,"pack_l1",lib
.pack('<l', 10) == string.char(10, 0, 0, 0)..l_pad
)
149 testlib
.test(OTHER
,"pack_l2",lib
.pack('>l', 10) == l_pad
..string.char(0, 0, 0, 10))
150 testlib
.test(OTHER
,"pack_l3",lib
.pack('<l', -10) == string.char(256-10, 256-1, 256-1, 256-1)..ln_pad
)
152 testlib
.testing(OTHER
, "unpack")
153 testlib
.test(OTHER
,"unpack_h1",lib
.unpack('<h', string.char(10, 0)) == 10)
154 testlib
.test(OTHER
,"unpack_h2",lib
.unpack('>h', string.char(0, 10)) == 10)
155 testlib
.test(OTHER
,"unpack_h3",lib
.unpack('<h', string.char(256-10, 256-1)) == -10)
157 testlib
.test(OTHER
,"unpack_l1",lib
.unpack('<l', string.char(10, 0, 0, 1)..l_pad
) == 10 + 2^
(3*8))
158 testlib
.test(OTHER
,"unpack_l2",lib
.unpack('>l', l_pad
..string.char(0, 1, 0, 10)) == 10 + 2^
(2*8))
159 testlib
.test(OTHER
,"unpack_l3",lib
.unpack('<l', string.char(256-10, 256-1, 256-1, 256-1)..ln_pad
) == -10)
162 lims
= {{'B', 255}, {'b', 127}, {'b', -128},
163 {'I1', 255}, {'i1', 127}, {'i1', -128},
164 {'H', 2^
16 - 1}, {'h', 2^
15 - 1}, {'h', -2^
15},
165 {'I2', 2^
16 - 1}, {'i2', 2^
15 - 1}, {'i2', -2^
15},
166 {'L', 2^
32 - 1}, {'l', 2^
31 - 1}, {'l', -2^
31},
167 {'I4', 2^
32 - 1}, {'i4', 2^
31 - 1}, {'i4', -2^
31},
170 for _
, a
in pairs
{'', '>', '<'} do
172 for _
, l
in pairs(lims
) do
173 local fmt
= a
.. l
[1]
174 testlib
.test(OTHER
,"limit"..i
.."("..l
[1]..")", lib
.unpack(fmt
, lib
.pack(fmt
, l
[2])) == l
[2])
180 testlib
.testing(OTHER
, "fixed-sized ints")
181 -- tests for fixed-sized ints
183 for _
, i
in pairs
{1,2,4} do
184 x
= lib
.pack('<i'..i
, -3)
185 testlib
.test(OTHER
,"pack_fixedlen"..num
, string.len(x
) == i
)
186 testlib
.test(OTHER
,"pack_fixed"..num
, x
== string.char(256-3) .. string.rep(string.char(256-1), i
-1))
187 testlib
.test(OTHER
,"unpack_fixed"..num
, lib
.unpack('<i'..i
, x
) == -3)
192 testlib
.testing(OTHER
, "alignment")
194 d
= lib
.pack("d", 5.1)
195 ali
= {[1] = string.char(1)..d
,
196 [2] = string.char(1, 0)..d
,
197 [4] = string.char(1, 0, 0, 0)..d
,
198 [8] = string.char(1, 0, 0, 0, 0, 0, 0, 0)..d
,
202 for a
,r
in pairs(ali
) do
203 testlib
.test(OTHER
,"pack_align"..num
, lib
.pack("!"..a
.."bd", 1, 5.1) == r
)
204 local x
,y
= lib
.unpack("!"..a
.."bd", r
)
205 testlib
.test(OTHER
,"unpack_align"..num
, x
== 1 and y
== 5.1)
210 testlib
.testing(OTHER
, "string")
212 testlib
.test(OTHER
,"string_pack1",lib
.pack("c", "alo alo") == "a")
213 testlib
.test(OTHER
,"string_pack2",lib
.pack("c4", "alo alo") == "alo ")
214 testlib
.test(OTHER
,"string_pack3",lib
.pack("c5", "alo alo") == "alo a")
215 testlib
.test(OTHER
,"string_pack4",lib
.pack("!4b>c7", 1, "alo alo") == "\1alo alo")
216 testlib
.test(OTHER
,"string_pack5",lib
.pack("!2<s", "alo alo") == "alo alo\0")
217 testlib
.test(OTHER
,"string_pack6",lib
.pack(" c0 ", "alo alo") == "alo alo")
219 for _
, f
in pairs
{"B", "l", "i2", "f", "d"} do
220 for _
, s
in pairs
{"", "a", "alo", string.rep("x", 200)} do
221 local x
= lib
.pack(f
.."c0", #s
, s
)
222 testlib
.test(OTHER
,"string_unpack"..num
, lib
.unpack(f
.."c0", x
) == s
)
228 testlib
.testing(OTHER
, "indeces")
230 x
= lib
.pack("!>iiiii", 1, 2, 3, 4, 5)
235 local v
, j
= lib
.unpack("!>i", x
, i
)
236 testlib
.test(OTHER
,"index_unpack"..num
, j
== i
+ 4 and v
== k
)
241 testlib
.testing(OTHER
, "absolute")
242 -- alignments are relative to 'absolute' positions
243 x
= lib
.pack("!8 xd", 12)
244 testlib
.test(OTHER
,"absolute_unpack1",lib
.unpack("!8d", x
, 3) == 12)
247 testlib
.test(OTHER
,"absolute_pack1",lib
.pack("<lhbxxH", -2, 10, -10, 250) ==
248 string.char(254, 255, 255, 255) ..ln_pad
.. string.char(10, 0, 246, 0, 0, 250, 0))
250 a
,b
,c
,d
= lib
.unpack("<lhbxxH",
251 string.char(254, 255, 255, 255) ..ln_pad
.. string.char(10, 0, 246, 0, 0, 250, 0))
252 testlib
.test(OTHER
,"absolute_unpack2",a
== -2 and b
== 10 and c
== -10 and d
== 250)
254 testlib
.test(OTHER
,"absolute_pack2",lib
.pack(">lBxxH", -20, 10, 250) ==
255 ln_pad
..string.char(255, 255, 255, 236, 10, 0, 0, 0, 250))
258 testlib
.testing(OTHER
, "position")
260 a
, b
, c
, d
= lib
.unpack(">lBxxH",
261 ln_pad
..string.char(255, 255, 255, 236, 10, 0, 0, 0, 250))
262 -- the 'd' return val is position in string, so will depend on size of long 'l'
263 local vald
= 10 + string.len(l_pad
)
264 testlib
.test(OTHER
,"position_unpack1",a
== -20 and b
== 10 and c
== 250 and d
== vald
)
266 a
,b
,c
,d
,e
= lib
.unpack(">fdfH",
267 '000'..lib
.pack(">fdfH", 3.5, -24e-5, 200.5, 30000),
269 testlib
.test(OTHER
,"position_unpack2",a
== 3.5 and b
== -24e-5 and c
== 200.5 and d
== 30000 and e
== 22)
271 a
,b
,c
,d
,e
= lib
.unpack("<fdxxfH",
272 '000'..lib
.pack("<fdxxfH", -13.5, 24e5
, 200.5, 300),
274 testlib
.test(OTHER
,"position_unpack3",a
== -13.5 and b
== 24e5
and c
== 200.5 and d
== 300 and e
== 24)
276 x
= lib
.pack(">I2fi4I2", 10, 20, -30, 40001)
277 testlib
.test(OTHER
,"position_pack1",string.len(x
) == 2+4+4+2)
278 testlib
.test(OTHER
,"position_unpack4",lib
.unpack(">f", x
, 3) == 20)
279 a
,b
,c
,d
= lib
.unpack(">i2fi4I2", x
)
280 testlib
.test(OTHER
,"position_unpack5",a
== 10 and b
== 20 and c
== -30 and d
== 40001)
282 testlib
.testing(OTHER
, "string length")
283 local s
= "hello hello"
284 x
= lib
.pack(" b c0 ", string.len(s
), s
)
285 testlib
.test(OTHER
,"stringlen_unpack1",lib
.unpack("bc0", x
) == s
)
286 x
= lib
.pack("Lc0", string.len(s
), s
)
287 testlib
.test(OTHER
,"stringlen_unpack2",lib
.unpack(" L c0 ", x
) == s
)
288 x
= lib
.pack("cc3b", s
, s
, 0)
289 testlib
.test(OTHER
,"stringlen_pack1",x
== "hhel\0")
290 testlib
.test(OTHER
,"stringlen_unpack3",lib
.unpack("xxxxb", x
) == 0)
292 testlib
.testing(OTHER
, "padding")
293 testlib
.test(OTHER
,"padding_pack1",lib
.pack("<!l", 3) == string.char(3, 0, 0, 0)..l_pad
)
294 testlib
.test(OTHER
,"padding_pack2",lib
.pack("<!xl", 3) == l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
)
295 testlib
.test(OTHER
,"padding_pack3",lib
.pack("<!xxl", 3) == l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
)
296 testlib
.test(OTHER
,"padding_pack4",lib
.pack("<!xxxl", 3) == l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
)
298 testlib
.test(OTHER
,"padding_unpack1",lib
.unpack("<!l", string.char(3, 0, 0, 0)..l_pad
) == 3)
299 testlib
.test(OTHER
,"padding_unpack2",lib
.unpack("<!xl", l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
) == 3)
300 testlib
.test(OTHER
,"padding_unpack3",lib
.unpack("<!xxl", l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
) == 3)
301 testlib
.test(OTHER
,"padding_unpack4",lib
.unpack("<!xxxl", l_pad
..string.char(0, 0, 0, 0, 3, 0, 0, 0)..l_pad
) == 3)
303 testlib
.testing(OTHER
, "format")
304 testlib
.test(OTHER
,"format_pack1",lib
.pack("<!2 b l h", 2, 3, 5) == string.char(2, 0, 3, 0)..l_pad
..string.char(0, 0, 5, 0))
305 a
,b
,c
= lib
.unpack("<!2blh", string.char(2, 0, 3, 0)..l_pad
..string.char(0, 0, 5, 0))
306 testlib
.test(OTHER
,"format_pack2",a
== 2 and b
== 3 and c
== 5)
308 testlib
.test(OTHER
,"format_pack3",lib
.pack("<!8blh", 2, 3, 5) == string.char(2, 0, 0, 0)..l_pad
..string.char(3, 0, 0, 0)..l_pad
..string.char(5, 0))
310 a
,b
,c
= lib
.unpack("<!8blh", string.char(2, 0, 0, 0)..l_pad
..string.char(3, 0, 0, 0)..l_pad
..string.char(5, 0))
311 testlib
.test(OTHER
,"format_pack4",a
== 2 and b
== 3 and c
== 5)
313 testlib
.test(OTHER
,"format_pack5",lib
.pack(">sh", "aloi", 3) == "aloi\0\0\3")
314 testlib
.test(OTHER
,"format_pack6",lib
.pack(">!sh", "aloi", 3) == "aloi\0\0\0\3")
316 x
= "aloi\0\0\0\0\3\2\0\0"
317 a
, b
, c
= lib
.unpack("<!si4", x
)
318 testlib
.test(OTHER
,"format_unpack1",a
== "aloi" and b
== 2*256+3 and c
== string.len(x
)+1)
320 x
= lib
.pack("!4sss", "hi", "hello", "bye")
321 a
,b
,c
= lib
.unpack("sss", x
)
322 testlib
.test(OTHER
,"format_unpack2",a
== "hi" and b
== "hello" and c
== "bye")
323 a
, i
= lib
.unpack("s", x
, 1)
324 testlib
.test(OTHER
,"format_unpack3",a
== "hi")
325 a
, i
= lib
.unpack("s", x
, i
)
326 testlib
.test(OTHER
,"format_unpack4",a
== "hello")
327 a
, i
= lib
.unpack("s", x
, i
)
328 testlib
.test(OTHER
,"format_unpack5",a
== "bye")
332 -- test for weird conditions
333 testlib
.testing(OTHER
, "weird conditions")
334 testlib
.test(OTHER
,"weird_pack1",lib
.pack(">>>h <!!!<h", 10, 10) == string.char(0, 10, 10, 0))
335 testlib
.test(OTHER
,"weird_pack2",not pcall(lib
.pack
, "!3l", 10))
336 testlib
.test(OTHER
,"weird_pack3",not pcall(lib
.pack
, "3", 10))
337 testlib
.test(OTHER
,"weird_pack4",not pcall(lib
.pack
, "i33", 10))
338 testlib
.test(OTHER
,"weird_pack5",not pcall(lib
.pack
, "I33", 10))
339 testlib
.test(OTHER
,"weird_pack6",lib
.pack("") == "")
340 testlib
.test(OTHER
,"weird_pack7",lib
.pack(" ") == "")
341 testlib
.test(OTHER
,"weird_pack8",lib
.pack(">>><<<!!") == "")
342 testlib
.test(OTHER
,"weird_unpack1",not pcall(lib
.unpack
, "c0", "alo"))
343 testlib
.test(OTHER
,"weird_unpack2",not pcall(lib
.unpack
, "s", "alo"))
344 testlib
.test(OTHER
,"weird_unpack3",lib
.unpack("s", "alo\0") == "alo")
345 testlib
.test(OTHER
,"weird_pack9",not pcall(lib
.pack
, "c4", "alo"))
346 testlib
.test(OTHER
,"weird_pack10",pcall(lib
.pack
, "c3", "alo"))
347 testlib
.test(OTHER
,"weird_unpack4",not pcall(lib
.unpack
, "c4", "alo"))
348 testlib
.test(OTHER
,"weird_unpack5",pcall(lib
.unpack
, "c3", "alo"))
349 testlib
.test(OTHER
,"weird_unpack6",not pcall(lib
.unpack
, "bc0", "\4alo"))
350 testlib
.test(OTHER
,"weird_unpack7",pcall(lib
.unpack
, "bc0", "\3alo"))
352 testlib
.test(OTHER
,"weird_unpack8",not pcall(lib
.unpack
, "b", "alo", 4))
353 testlib
.test(OTHER
,"weird_unpack9",lib
.unpack("b", "alo\3", 4) == 3)
355 testlib
.test(OTHER
,"weird_pack11",not pcall(lib
.pack
, "\250\22", "alo"))
356 testlib
.test(OTHER
,"weird_pack12",not pcall(lib
.pack
, 1, "alo"))
357 testlib
.test(OTHER
,"weird_pack13",not pcall(lib
.pack
, nil, "alo"))
358 testlib
.test(OTHER
,"weird_pack14",not pcall(lib
.pack
, {}, "alo"))
359 testlib
.test(OTHER
,"weird_pack15",not pcall(lib
.pack
, true, "alo"))
360 testlib
.test(OTHER
,"weird_unpack10",not pcall(lib
.unpack
, "\250\22", "\3alo"))
361 testlib
.test(OTHER
,"weird_unpack11",not pcall(lib
.unpack
, 1, "\3alo"))
362 testlib
.test(OTHER
,"weird_unpack12",not pcall(lib
.unpack
, nil, "\3alo"))
363 testlib
.test(OTHER
,"weird_unpack13",not pcall(lib
.unpack
, {}, "\3alo"))
364 testlib
.test(OTHER
,"weird_unpack14",not pcall(lib
.unpack
, true, "\3alo"))