Skip to content

Commit

Permalink
Prevent assignment of invalid struct fields (fixes ctypesgen#183)
Browse files Browse the repository at this point in the history
  • Loading branch information
mara004 committed Jan 24, 2024
1 parent 0f0c5d6 commit e8fb89e
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions ctypesgen/printer_python/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,13 @@ def print_typedef(self, typedef):
def print_struct(self, struct):
self.srcinfo(struct.src)
base = {"union": "Union", "struct": "Structure"}[struct.variety]
self.file.write("class %s_%s(%s):\n" " pass\n" % (struct.variety, struct.tag, base))

def print_struct_members(self, struct):
self.file.write("class %s_%s(%s):\n" % (struct.variety, struct.tag, base))
pad = " "*4
if struct.opaque:
self.file.write(pad + "pass")
return

# is this supposed to be packed?
if struct.attrib.get("packed", False):
aligned = struct.attrib.get("aligned", [1])
Expand All @@ -243,7 +244,7 @@ def print_struct_members(self, struct):
if isinstance(aligned, ExpressionNode):
# TODO: for non-constant expression nodes, this will fail:
aligned = aligned.evaluate(None)
self.file.write("{}_{}._pack_ = {}\n".format(struct.variety, struct.tag, aligned))
self.file.write(pad + f"_pack_ = {aligned}\n")

# handle unnamed fields.
unnamed_fields = []
Expand All @@ -264,16 +265,24 @@ def print_struct_members(self, struct):
unnamed_fields.append(name)
struct.members[mi] = mem

self.file.write("%s_%s.__slots__ = [\n" % (struct.variety, struct.tag))
self.file.write(pad + "__slots__ = [\n")
for name, ctype in struct.members:
self.file.write(" '%s',\n" % name)
self.file.write("]\n")

self.file.write(pad*2 + f"'{name}',\n")
self.file.write(pad + "]\n")
if len(unnamed_fields) > 0:
self.file.write("%s_%s._anonymous_ = [\n" % (struct.variety, struct.tag))
self.file.write(pad + "_anonymous_ = [\n")
for name in unnamed_fields:
self.file.write(" '%s',\n" % name)
self.file.write("]\n")
self.file.write(pad*2 + f" '{name}',\n")
self.file.write(pad + "]\n")


def print_struct_members(self, struct):
# Fields are defined indepedent of the actual class to handle forward declarations, including self-references and cyclic structs
# https://docs.python.org/3/library/ctypes.html#incomplete-types

if struct.opaque:
return

self.file.write("%s_%s._fields_ = [\n" % (struct.variety, struct.tag))
for name, ctype in struct.members:
Expand Down

0 comments on commit e8fb89e

Please sign in to comment.