Skip to content

Commit f337b0d

Browse files
committed
Add check for duplicate members
1 parent a4fa6fb commit f337b0d

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

cstruct/c_parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def parse_type(tokens: Tokens, __cls__: Type['AbstractCStruct'], byte_order: Opt
7878
# signed/unsigned/struct
7979
if c_type in ['signed', 'unsigned', 'struct', 'union'] and len(tokens) > 1:
8080
c_type = c_type + " " + tokens.pop()
81-
81+
8282
vlen = 1
8383
flexible_array = False
8484

@@ -195,6 +195,8 @@ def parse_struct(
195195
raise CStructException("Flexible array member must be the last member of such a struct")
196196
field_type = parse_type(tokens, __cls__, __byte_order__, offset)
197197
vname = tokens.pop()
198+
if vname in fields_types:
199+
raise ParserError("Duplicate member '{}'".format(vname))
198200
fields_types[vname] = field_type
199201
# calculate the max field size (for the alignment)
200202
max_alignment = max(max_alignment, field_type.alignment)
@@ -204,7 +206,7 @@ def parse_struct(
204206
offset = field_type.offset + field_type.vsize
205207
t = tokens.pop()
206208
if t != ';':
207-
raise ParserError("; expected but %s found" % t)
209+
raise ParserError("; expected but {} found".format(t))
208210

209211
if __is_union__: # C union
210212
# Calculate the sizeof union as size of its largest element

tests/test_cstruct.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
#
2626
# *****************************************************************************
2727

28+
import pytest
2829
import cstruct
2930
from cstruct import sizeof, typedef
3031
import io
3132
import os
3233
from pathlib import Path
34+
from cstruct.exceptions import ParserError
3335

3436
MBR_DATA = (Path(__file__).parent.parent / 'mbr').read_bytes()
3537

@@ -255,3 +257,11 @@ def test_null_compare():
255257
c = Dummy()
256258
assert c is not None
257259
assert c != None
260+
261+
262+
def test_invalid_inline():
263+
with pytest.raises(ParserError):
264+
cstruct.MemCStruct.parse(
265+
'struct { unsigned char head; unsigned char head; }', __byte_order__=cstruct.LITTLE_ENDIAN
266+
)
267+
assert False

tests/test_memcstruct.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
#
2626
# *****************************************************************************
2727

28+
import pytest
2829
import cstruct
2930
from cstruct import sizeof, typedef
3031
import os
3132
from pathlib import Path
33+
from cstruct.exceptions import ParserError
3234

3335
MBR_DATA = (Path(__file__).parent.parent / 'mbr').read_bytes()
3436

@@ -249,3 +251,11 @@ def test_null_compare():
249251
c = Dummy()
250252
assert c is not None
251253
assert c != None
254+
255+
256+
def test_invalid_inline():
257+
with pytest.raises(ParserError):
258+
cstruct.MemCStruct.parse(
259+
'struct { unsigned char head; unsigned char head; }', __byte_order__=cstruct.LITTLE_ENDIAN
260+
)
261+
assert False

0 commit comments

Comments
 (0)