Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion dissect/cstruct/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
Structure,
Union,
Void,
VoidArray,
Wchar,
WcharArray,
)
Expand Down Expand Up @@ -48,6 +49,7 @@
Void,
Wchar,
WcharArray,
VoidArray,
)

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -365,7 +367,7 @@ def _generate_struct_info(cs: cstruct, fields: list[Field], align: bool = False)
read_type = _get_read_type(cs, field.type)

# Drop voids
if issubclass(read_type, Void):
if issubclass(read_type, (Void, VoidArray)):
continue

# Array of more complex types are handled elsewhere
Expand Down
3 changes: 2 additions & 1 deletion dissect/cstruct/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from dissect.cstruct.types.packed import Packed
from dissect.cstruct.types.pointer import Pointer
from dissect.cstruct.types.structure import Field, Structure, Union
from dissect.cstruct.types.void import Void
from dissect.cstruct.types.void import Void, VoidArray
from dissect.cstruct.types.wchar import Wchar, WcharArray

__all__ = [
Expand All @@ -27,6 +27,7 @@
"Structure",
"Union",
"Void",
"VoidArray",
"Wchar",
"WcharArray",
]
4 changes: 4 additions & 0 deletions dissect/cstruct/types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ def __getitem__(cls, num_entries: int | Expression | None) -> type[BaseArray]:
"""Create a new array with the given number of entries."""
return cls.cs._make_array(cls, num_entries)

def __bool__(cls) -> bool:
"""Type class is always truthy."""
return True

def __len__(cls) -> int:
"""Return the byte size of the type."""
# Python 3.9 compat thing for bound type vars
Expand Down
31 changes: 24 additions & 7 deletions dissect/cstruct/types/void.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,44 @@
from __future__ import annotations

from typing import Any, BinaryIO
from typing import TYPE_CHECKING, Any, BinaryIO

from dissect.cstruct.types.base import BaseType
from dissect.cstruct.types.base import BaseArray, BaseType

if TYPE_CHECKING:
from typing_extensions import Self

Check warning on line 8 in dissect/cstruct/types/void.py

View check run for this annotation

Codecov / codecov/patch

dissect/cstruct/types/void.py#L8

Added line #L8 was not covered by tests


class VoidArray(list, BaseArray):
"""Character array type for reading and writing byte strings."""

@classmethod
def __default__(cls) -> Self:
return cls()

@classmethod
def _read(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Self:
return cls()

@classmethod
def _write(cls, stream: BinaryIO, data: bytes) -> int:
return 0


class Void(BaseType):
"""Void type."""

ArrayType = VoidArray

def __bool__(self) -> bool:
return False

def __eq__(self, value: object) -> bool:
return isinstance(value, Void)

@classmethod
def _read(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Void:
def _read(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Self:
return cls.__new__(cls)

@classmethod
def _read_0(cls, stream: BinaryIO, context: dict[str, Any] | None = None) -> Void:
return [cls.__new__(cls)]

@classmethod
def _write(cls, stream: BinaryIO, data: Void) -> int:
return 0
9 changes: 9 additions & 0 deletions tests/test_types_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,12 @@ def _read(cls, stream: BinaryIO, context: dict | None = None) -> CustomType:
assert isinstance(result.b, CustomType)
assert result.a.value == b"ASDF"
assert result.b.value == b"asdf"


def test_truthy_type(cs: cstruct) -> None:
static_type = cs.uint32
dynamic_type = cs.uint32[None]

assert static_type
# Should not raise a TypeError: Dynamic size
assert dynamic_type
16 changes: 9 additions & 7 deletions tests/test_types_void.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@


def test_void_read(cs: cstruct) -> None:
assert not cs.void
# The type itself is truthy, but an instance is not
assert cs.void
assert not cs.void()

stream = io.BytesIO(b"AAAA")
assert not cs.void(stream)
Expand All @@ -23,11 +25,11 @@ def test_void_write(cs: cstruct) -> None:


def test_void_array_read(cs: cstruct) -> None:
assert not cs.void[4]
assert not cs.void[4]()

stream = io.BytesIO(b"AAAA")
assert not any(cs.void[4](stream))
assert not any(cs.void[None](stream))
assert not cs.void[4](stream)
assert not cs.void[None](stream)
assert stream.tell() == 0


Expand All @@ -41,7 +43,7 @@ def test_void_default(cs: cstruct) -> None:
assert not cs.void()
assert not cs.void.__default__()

assert cs.void[1].__default__() == [cs.void()]
assert cs.void[1].__default__() == []
assert cs.void[None].__default__() == []


Expand All @@ -61,8 +63,8 @@ def test_void_struct(cs: cstruct, compiled: bool) -> None:

obj = cs.test(stream)
assert not obj.a
assert not any(obj.b)
assert not any(obj.c)
assert not obj.b
assert not obj.c

assert stream.tell() == 0

Expand Down