dissect.cstruct 4.1.dev1__tar.gz → 4.2.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {dissect_cstruct-4.1.dev1/dissect.cstruct.egg-info → dissect_cstruct-4.2.dev1}/PKG-INFO +1 -1
  2. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/structure.py +10 -4
  3. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/utils.py +3 -1
  4. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1/dissect.cstruct.egg-info}/PKG-INFO +1 -1
  5. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_enum.py +63 -23
  6. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_flag.py +37 -15
  7. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_utils.py +25 -0
  8. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/COPYRIGHT +0 -0
  9. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/LICENSE +0 -0
  10. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/MANIFEST.in +0 -0
  11. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/README.md +0 -0
  12. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/__init__.py +0 -0
  13. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/bitbuffer.py +0 -0
  14. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/compiler.py +0 -0
  15. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/cstruct.py +0 -0
  16. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/exceptions.py +0 -0
  17. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/expression.py +0 -0
  18. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/parser.py +0 -0
  19. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/__init__.py +0 -0
  20. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/base.py +0 -0
  21. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/char.py +0 -0
  22. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/enum.py +0 -0
  23. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/flag.py +0 -0
  24. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/int.py +0 -0
  25. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/leb128.py +0 -0
  26. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/packed.py +0 -0
  27. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/pointer.py +0 -0
  28. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/void.py +0 -0
  29. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect/cstruct/types/wchar.py +0 -0
  30. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect.cstruct.egg-info/SOURCES.txt +0 -0
  31. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect.cstruct.egg-info/dependency_links.txt +0 -0
  32. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/dissect.cstruct.egg-info/top_level.txt +0 -0
  33. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/examples/disk.py +0 -0
  34. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/examples/mirai.py +0 -0
  35. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/examples/pe.py +0 -0
  36. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/examples/protobuf.py +0 -0
  37. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/examples/secdesc.py +0 -0
  38. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/pyproject.toml +0 -0
  39. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/setup.cfg +0 -0
  40. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/__init__.py +0 -0
  41. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/conftest.py +0 -0
  42. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/data/testdef.txt +0 -0
  43. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/docs/Makefile +0 -0
  44. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/docs/conf.py +0 -0
  45. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/docs/index.rst +0 -0
  46. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_align.py +0 -0
  47. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_basic.py +0 -0
  48. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_bitbuffer.py +0 -0
  49. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_bitfield.py +0 -0
  50. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_compiler.py +0 -0
  51. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_ctypes.py +0 -0
  52. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_expression.py +0 -0
  53. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_parser.py +0 -0
  54. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_base.py +0 -0
  55. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_char.py +0 -0
  56. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_custom.py +0 -0
  57. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_int.py +0 -0
  58. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_leb128.py +0 -0
  59. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_packed.py +0 -0
  60. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_pointer.py +0 -0
  61. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_structure.py +0 -0
  62. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_union.py +0 -0
  63. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_void.py +0 -0
  64. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/test_types_wchar.py +0 -0
  65. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tests/utils.py +0 -0
  66. {dissect_cstruct-4.1.dev1 → dissect_cstruct-4.2.dev1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.cstruct
3
- Version: 4.1.dev1
3
+ Version: 4.2.dev1
4
4
  Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Apache License 2.0
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import io
4
4
  from contextlib import contextmanager
5
+ from enum import Enum
5
6
  from functools import lru_cache
6
7
  from operator import attrgetter
7
8
  from textwrap import dedent
@@ -380,10 +381,15 @@ class Structure(BaseType, metaclass=StructureMetaType):
380
381
  return getattr(self, item)
381
382
 
382
383
  def __repr__(self) -> str:
383
- values = [
384
- f"{k}={hex(self[k]) if (issubclass(f.type, int) and not issubclass(f.type, Pointer)) else repr(self[k])}"
385
- for k, f in self.__class__.fields.items()
386
- ]
384
+ values = []
385
+ for name, field in self.__class__.fields.items():
386
+ value = self[name]
387
+ if issubclass(field.type, int) and not issubclass(field.type, (Pointer, Enum)):
388
+ value = hex(value)
389
+ else:
390
+ value = repr(value)
391
+ values.append(f"{name}={value}")
392
+
387
393
  return f"<{self.__class__.__name__} {' '.join(values)}>"
388
394
 
389
395
 
@@ -3,8 +3,10 @@ from __future__ import annotations
3
3
  import pprint
4
4
  import string
5
5
  import sys
6
+ from enum import Enum
6
7
  from typing import Iterator
7
8
 
9
+ from dissect.cstruct.types.pointer import Pointer
8
10
  from dissect.cstruct.types.structure import Structure
9
11
 
10
12
  COLOR_RED = "\033[1;31m"
@@ -158,7 +160,7 @@ def _dumpstruct(
158
160
  ci += 1
159
161
 
160
162
  value = getattr(structure, field.name)
161
- if isinstance(value, str):
163
+ if isinstance(value, (str, Pointer, Enum)):
162
164
  value = repr(value)
163
165
  elif isinstance(value, int):
164
166
  value = hex(value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.cstruct
3
- Version: 4.1.dev1
3
+ Version: 4.2.dev1
4
4
  Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Apache License 2.0
@@ -98,6 +98,66 @@ def test_enum_eof(TestEnum: type[Enum]) -> None:
98
98
  TestEnum[None](b"\x01")
99
99
 
100
100
 
101
+ def test_enum_same_value_different_type(cs: cstruct, compiled: bool) -> None:
102
+ cdef = """
103
+ enum Test16 : uint16 {
104
+ A = 0x1,
105
+ B = 0x2
106
+ };
107
+
108
+ enum Test24 : uint24 {
109
+ A = 0x1,
110
+ B = 0x2
111
+ };
112
+
113
+ enum Test32 : uint32 {
114
+ A = 0x1,
115
+ B = 0x2
116
+ };
117
+ """
118
+ cs.load(cdef, compiled=compiled)
119
+
120
+ obj = {
121
+ cs.Test16.A: "Test16.A",
122
+ cs.Test16.B: "Test16.B",
123
+ cs.Test24.A: "Test24.A",
124
+ cs.Test24.B: "Test24.B",
125
+ }
126
+
127
+ assert obj[cs.Test16.A] == "Test16.A"
128
+ assert obj[cs.Test16(2)] == "Test16.B"
129
+ assert obj[cs.Test24(1)] == "Test24.A"
130
+ assert obj[cs.Test24.B] == "Test24.B"
131
+
132
+ with pytest.raises(KeyError):
133
+ obj[cs.Test32.A]
134
+
135
+
136
+ def test_enum_str_repr(TestEnum: type[Enum]) -> None:
137
+ assert repr(TestEnum.A) == "<Test.A: 1>"
138
+ assert str(TestEnum.A) == "Test.A"
139
+ assert repr(TestEnum(69)) == "<Test: 69>"
140
+ assert str(TestEnum(69)) == "Test.69"
141
+
142
+
143
+ def test_enum_str_repr_in_struct(cs: cstruct, compiled: bool) -> None:
144
+ cdef = """
145
+ enum Test16 : uint16 {
146
+ A = 0x1,
147
+ B = 0x2
148
+ };
149
+
150
+ struct test {
151
+ Test16 a;
152
+ };
153
+ """
154
+ cs.load(cdef, compiled=compiled)
155
+
156
+ obj = cs.test(b"\x02\x00")
157
+ assert repr(obj) == "<test a=<Test16.B: 2>>"
158
+ assert str(obj) == "<test a=<Test16.B: 2>>"
159
+
160
+
101
161
  def test_enum_struct(cs: cstruct, compiled: bool) -> None:
102
162
  cdef = """
103
163
  enum Test16 : uint16 {
@@ -174,26 +234,6 @@ def test_enum_struct(cs: cstruct, compiled: bool) -> None:
174
234
  assert cs.test_expr(buf).expr == [cs.Test16.A, cs.Test16.B]
175
235
  assert cs.test_expr(size=1, expr=[cs.Test16.A, cs.Test16.B]).dumps() == buf
176
236
 
177
- obj = {
178
- cs.Test16.A: "Test16.A",
179
- cs.Test16.B: "Test16.B",
180
- cs.Test24.A: "Test24.A",
181
- cs.Test24.B: "Test24.B",
182
- }
183
-
184
- assert obj[cs.Test16.A] == "Test16.A"
185
- assert obj[cs.Test16(2)] == "Test16.B"
186
- assert obj[cs.Test24(1)] == "Test24.A"
187
- assert obj[cs.Test24.B] == "Test24.B"
188
-
189
- with pytest.raises(KeyError):
190
- obj[cs.Test32.A]
191
-
192
- assert repr(cs.Test16.A) == "<Test16.A: 1>"
193
- assert str(cs.Test16.A) == "Test16.A"
194
- assert repr(cs.Test16(69)) == "<Test16: 69>"
195
- assert str(cs.Test16(69)) == "Test16.69"
196
-
197
237
 
198
238
  def test_enum_comments(cs: cstruct) -> None:
199
239
  cdef = """
@@ -259,7 +299,7 @@ def test_enum_name(cs: cstruct, compiled: bool) -> None:
259
299
  Color = cs.Color
260
300
  Pixel = cs.Pixel
261
301
 
262
- pixel = Pixel(b"\xFF\x0A\x01\x00\xAA\xBB\xCC\xDD")
302
+ pixel = Pixel(b"\xff\x0a\x01\x00\xaa\xbb\xcc\xdd")
263
303
  assert pixel.x == 255
264
304
  assert pixel.y == 10
265
305
  assert pixel.color.name == "RED"
@@ -267,7 +307,7 @@ def test_enum_name(cs: cstruct, compiled: bool) -> None:
267
307
  assert pixel.color.value == 1
268
308
  assert pixel.hue == 0xDDCCBBAA
269
309
 
270
- pixel = Pixel(b"\x00\x00\xFF\x00\xAA\xBB\xCC\xDD")
310
+ pixel = Pixel(b"\x00\x00\xff\x00\xaa\xbb\xcc\xdd")
271
311
  assert pixel.color.name is None
272
312
  assert pixel.color.value == 0xFF
273
313
  assert repr(pixel.color) == "<Color: 255>"
@@ -350,7 +390,7 @@ def test_enum_anonymous_struct(cs: cstruct, compiled: bool) -> None:
350
390
 
351
391
  test = cs.test
352
392
 
353
- t = test(b"\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00")
393
+ t = test(b"\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00")
354
394
  assert t.arr == [255, 0, 0, 10]
355
395
 
356
396
 
@@ -62,6 +62,42 @@ def test_flag_operator(TestFlag: type[Flag]) -> None:
62
62
  assert TestFlag[2]([TestFlag.B, (TestFlag.A | TestFlag.B)]).dumps() == b"\x02\x03"
63
63
 
64
64
 
65
+ def test_flag_str_repr(TestFlag: type[Flag]) -> None:
66
+ if PY_311:
67
+ assert repr(TestFlag.A | TestFlag.B) == "<Test.A|B: 3>"
68
+ assert str(TestFlag.A | TestFlag.B) == "Test.A|B"
69
+ assert repr(TestFlag(69)) == "<Test.A|68: 69>"
70
+ assert str(TestFlag(69)) == "Test.A|68"
71
+ else:
72
+ assert repr(TestFlag.A | TestFlag.B) == "<Test.B|A: 3>"
73
+ assert str(TestFlag.A | TestFlag.B) == "Test.B|A"
74
+ assert repr(TestFlag(69)) == "<Test.64|4|A: 69>"
75
+ assert str(TestFlag(69)) == "Test.64|4|A"
76
+
77
+
78
+ def test_flag_str_repr_in_struct(cs: cstruct, compiled: bool) -> None:
79
+ cdef = """
80
+ flag Test : uint16 {
81
+ A,
82
+ B
83
+ };
84
+
85
+ struct test {
86
+ Test a;
87
+ };
88
+ """
89
+ cs.load(cdef, compiled=compiled)
90
+
91
+ obj = cs.test(b"\x03\x00")
92
+
93
+ if PY_311:
94
+ assert repr(obj) == "<test a=<Test.A|B: 3>>"
95
+ assert str(obj) == "<test a=<Test.A|B: 3>>"
96
+ else:
97
+ assert repr(obj) == "<test a=<Test.B|A: 3>>"
98
+ assert str(obj) == "<test a=<Test.B|A: 3>>"
99
+
100
+
65
101
  def test_flag_struct(cs: cstruct) -> None:
66
102
  cdef = """
67
103
  flag Test {
@@ -101,20 +137,6 @@ def test_flag_struct(cs: cstruct) -> None:
101
137
  assert bool(cs.Test(1)) is True
102
138
 
103
139
  assert cs.Test.a | cs.Test.b == 3
104
- if PY_311:
105
- assert repr(cs.Test.c | cs.Test.d) == "<Test.c|d: 12>"
106
- assert str(cs.Test.c | cs.Test.d) == "Test.c|d"
107
- assert repr(cs.Test.a | cs.Test.b) == "<Test.a|b: 3>"
108
- assert str(cs.Test.a | cs.Test.b) == "Test.a|b"
109
- assert repr(cs.Test(69)) == "<Test.a|c|64: 69>"
110
- assert str(cs.Test(69)) == "Test.a|c|64"
111
- else:
112
- assert repr(cs.Test.c | cs.Test.d) == "<Test.d|c: 12>"
113
- assert str(cs.Test.c | cs.Test.d) == "Test.d|c"
114
- assert repr(cs.Test.a | cs.Test.b) == "<Test.b|a: 3>"
115
- assert str(cs.Test.a | cs.Test.b) == "Test.b|a"
116
- assert repr(cs.Test(69)) == "<Test.64|c|a: 69>"
117
- assert str(cs.Test(69)) == "Test.64|c|a"
118
140
  assert cs.Test(2) == cs.Test.b
119
141
  assert cs.Test(3) == cs.Test.a | cs.Test.b
120
142
  assert cs.Test.c & 12 == cs.Test.c
@@ -231,5 +253,5 @@ def test_flag_anonymous_struct(cs: cstruct, compiled: bool) -> None:
231
253
 
232
254
  test = cs.test
233
255
 
234
- t = test(b"\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00")
256
+ t = test(b"\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00")
235
257
  assert t.arr == [255, 0, 0, 10]
@@ -86,6 +86,31 @@ def test_dumpstruct_anonymous(cs: cstruct, capsys: pytest.CaptureFixture, compil
86
86
  assert str(excinfo.value) == "Invalid output argument: 'generator' (should be 'print' or 'string')."
87
87
 
88
88
 
89
+ def test_dumpstruct_enum(cs: cstruct, compiled: bool) -> None:
90
+ cdef = """
91
+ enum Test16 : uint16 {
92
+ A = 0x1,
93
+ B = 0x2
94
+ };
95
+
96
+ struct test {
97
+ Test16 testval;
98
+ };
99
+ """
100
+ cs.load(cdef, compiled=compiled)
101
+
102
+ assert verify_compiled(cs.test, compiled)
103
+
104
+ buf = b"\x02\x00"
105
+ obj = cs.test(buf)
106
+
107
+ out1 = utils.dumpstruct(cs.test, buf, output="string")
108
+ out2 = utils.dumpstruct(obj, output="string")
109
+
110
+ assert "<Test16.B: 2>" in out1
111
+ assert "<Test16.B: 2>" in out2
112
+
113
+
89
114
  def test_pack_unpack() -> None:
90
115
  endian = "little"
91
116
  sign = False