Skip to content

Commit 322424e

Browse files
committed
version 6.1 - fix CStruct.pack() padding
1 parent 5a8a7c6 commit 322424e

File tree

5 files changed

+83
-2
lines changed

5 files changed

+83
-2
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ black: isort
2727
clean:
2828
-rm -rf build dist
2929
-rm -rf *.egg-info
30-
-rm -rf bin lib share pyvenv.cfg
30+
-rm -rf bin lib lib64 share include pyvenv.cfg
3131

3232
coverage:
3333
@pytest --cov --cov-report=term-missing

changelog.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,9 @@
192192
### Improved
193193

194194
- Python 3.13 support
195+
196+
## [6.1] - 2025-03-21
197+
198+
### Fix
199+
200+
- fix CStruct.pack() padding

cstruct/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
__author__ = "Andrea Bonomi <andrea.bonomi@gmail.com>"
2626
__license__ = "MIT"
27-
__version__ = "6.0"
27+
__version__ = "6.1"
2828
__date__ = "15 August 2013"
2929

3030
from typing import Any, Dict, Optional, Type, Union

cstruct/cstruct.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def pack(self) -> bytes:
6666
"""
6767
result: List[bytes] = []
6868
for field, field_type in self.__fields_types__.items():
69+
# Add padding if needed
70+
if field_type.padding:
71+
result.append(CHAR_ZERO * field_type.padding)
72+
6973
if field_type.is_struct or field_type.is_union:
7074
if field_type.vlen == 1: # single struct
7175
v = getattr(self, field, field_type.ref())

tests/test_padding.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python
2+
3+
import cstruct
4+
from cstruct import LITTLE_ENDIAN, NATIVE_ORDER, sizeof
5+
6+
DEFINITION = """
7+
struct struct1 {
8+
char a[2];
9+
uint32_t b;
10+
}
11+
"""
12+
13+
14+
class CStructNative(cstruct.CStruct):
15+
__byte_order__ = NATIVE_ORDER
16+
__def__ = DEFINITION
17+
18+
19+
class MemCStructNative(cstruct.MemCStruct):
20+
__byte_order__ = NATIVE_ORDER
21+
__def__ = DEFINITION
22+
23+
24+
class CStructLittleEndian(cstruct.CStruct):
25+
__byte_order__ = LITTLE_ENDIAN
26+
__def__ = DEFINITION
27+
28+
29+
class MemCStructLittleEndian(cstruct.MemCStruct):
30+
__byte_order__ = LITTLE_ENDIAN
31+
__def__ = DEFINITION
32+
33+
34+
def test_memcstruct_padding():
35+
for struct in (CStructNative, MemCStructNative):
36+
data = b"\x41\x42\x00\x00\x01\x00\x00\x00"
37+
assert sizeof(struct) == 8
38+
t = struct()
39+
t.unpack(data)
40+
assert t.a == b"AB"
41+
assert t.b == 1
42+
buf = t.pack()
43+
assert len(buf) == sizeof(struct)
44+
assert buf == data
45+
46+
t2 = struct()
47+
t2.unpack(buf)
48+
assert t2.a == b"AB"
49+
assert t2.b == 1
50+
buf = t.pack()
51+
assert len(buf) == sizeof(struct)
52+
53+
54+
def test_no_padding():
55+
for struct in (CStructLittleEndian, MemCStructLittleEndian):
56+
data = b"\x41\x42\x01\x00\x00\x00"
57+
assert sizeof(struct) == 6
58+
t = struct()
59+
t.unpack(data)
60+
assert t.a == b"AB"
61+
assert t.b == 1
62+
buf = t.pack()
63+
assert len(buf) == sizeof(struct)
64+
assert buf == data
65+
66+
t2 = struct()
67+
t2.unpack(buf)
68+
assert t2.a == b"AB"
69+
assert t2.b == 1
70+
buf = t.pack()
71+
assert len(buf) == sizeof(struct)

0 commit comments

Comments
 (0)