Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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):
"""Array type representing void elements, primarily used for no-op reading and writing operations."""

@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