Skip to content

Commit

Permalink
python: Generate missing constraint validation for traversed children
Browse files Browse the repository at this point in the history
The following pattern is missing constraint validation in the generated
code:

```
packet A {
  a: 8,
  b: 8,
  _payload_,
}

packet B : A (a = 1) {
  _payload_,
}

packet C : B (b = 1) {}
packet D : B (b = 2) {}
```

The constraint a == 1 is not validated in either C or D
  • Loading branch information
hchataing committed Oct 30, 2023
1 parent aeafb1b commit 8c3b028
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
11 changes: 4 additions & 7 deletions pdl-compiler/scripts/generate_python_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,9 +904,10 @@ def generate_packet_parser(packet: ast.Declaration) -> List[str]:

# Convert the packet constraints to a boolean expression.
validation = []
if packet.constraints:
constraints = core.get_all_packet_constraints(packet)
if constraints:
cond = []
for c in packet.constraints:
for c in constraints:
if c.value is not None:
cond.append(f"fields['{c.id}'] != {hex(c.value)}")
else:
Expand Down Expand Up @@ -989,11 +990,7 @@ def generate_packet_post_init(decl: ast.Declaration) -> List[str]:
"""Generate __post_init__ function to set constraint field values."""

# Gather all constraints from parent packets.
constraints = []
current = decl
while current.parent_id:
constraints.extend(current.constraints)
current = current.parent
constraints = core.get_all_packet_constraints(decl)

if constraints:
code = []
Expand Down
13 changes: 13 additions & 0 deletions pdl-compiler/scripts/pdl/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,19 @@ def get_derived_packets(
return children


def get_all_packet_constraints(
decl: Union[PacketDeclaration, StructDeclaration]
) -> List[Constraint]:
"""Return the list of constraints defined in the selected packet and
its parent declarations."""

constraints = []
while decl.parent_id:
constraints.extend(decl.constraints)
decl = decl.parent
return constraints


def get_field_size(field: Field, skip_payload: bool = False) -> Optional[int]:
"""Determine the size of a field in bits, if possible.
If the field is dynamically sized (e.g. unsized array or payload field),
Expand Down

0 comments on commit 8c3b028

Please sign in to comment.