Skip to content

Commit

Permalink
Fixed VLA/VSA for all types.
Browse files Browse the repository at this point in the history
Null termination removed.
  • Loading branch information
Hadatko committed Dec 20, 2019
1 parent 16ea409 commit c45c670
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions dissect/cstruct/cstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ class Array(BaseType):
When using the default C-style parser, the following syntax is supported:
x[3] -> 3 -> static length.
x[] -> None -> null-terminated.
x[] -> None -> length based on data buf length (to the end of buffer) (VLA/VSA).
x[expr] -> expr -> dynamic length.
"""

Expand Down Expand Up @@ -1522,14 +1522,30 @@ def gen_struct_class(self, structure):
num = 'max(0, Expression(self.cstruct, "{expr}").evaluate(r))'.format(
expr=num.expr
)

struct_read += (
'r["{name}"] = []\n'
'for _ in xrange({num}):\n'
' r["{name}"].append(self.cstruct.{struct_name}._read(stream))\n'.format(
name=field.name, num=num, struct_name=ft.type.name
if ft.dynamic: #To the end of buffer
struct_read += (
'r["{name}"] = []\n'
'while True:\n'
' bufSize = stream.getbuffer().nbytes\n'
' bufPos = stream.tell()\n'
' try:'
' a = self.cstruct.{struct_name}._read(stream)\n'
' except:\n'
' if bufSize == bufPos:\n'
' break;\n'
' raise EOFError()\n'
' r["{name}"].append(a)\n'.format(
name=field.name, num=num, struct_name=ft.type.name
)
)
else:
struct_read += (
'r["{name}"] = []\n'
'for _ in xrange({num}):\n'
' r["{name}"].append(self.cstruct.{struct_name}._read(stream))\n'.format(
name=field.name, num=num, struct_name=ft.type.name
)
)
)
else:
struct_read += 'r["{name}"] = self.cstruct.{struct_name}._read(stream)\n'.format(
name=field.name, struct_name=ft.name
Expand Down Expand Up @@ -1713,14 +1729,14 @@ def gen_dynamic_block(self, field):
t = field.type.type
reader = None

if not field.type.count: # Null terminated
if not field.type.count: #To the end of buffer
if isinstance(t, PackedType):
reader = (
't = []\nwhile True:\n'
' d = stream.read({size})\n'
' if len(d) == 0: break\n'
' if len(d) != {size}: raise EOFError()\n'
' v = struct.unpack(self.cstruct.endian + "{packchar}", d)[0]\n'
' if v == 0: break\n'
' t.append(v)'.format(size=t.size, packchar=t.packchar)
)

Expand All @@ -1738,14 +1754,14 @@ def gen_dynamic_block(self, field):

if isinstance(t, WcharType):
reader += ".decode('utf-16-le' if self.cstruct.endian == '<' else 'utf-16-be')"
elif isinstance(t, BytesInteger):
elif isinstance(t, BytesInteger): #To the end of buffer
reader = (
't = []\n'
'while True:\n'
' d = stream.read({size})\n'
' if len(d) == 0: break\n'
' if len(d) != {size}: raise EOFError()\n'
' v = BytesInteger.parse(d, {size}, 1, {signed}, self.cstruct.endian)\n'
' if v == 0: break\n'
' t.append(v)'.format(size=t.size, signed=t.signed)
)

Expand Down

0 comments on commit c45c670

Please sign in to comment.