Skip to content

Payload type reuse across registers is unvalidated in both generator targets #122

Description

@glopesdev

Both generator targets reuse a payload type across registers by name alone, without checking that the registers agree on what that type describes. A register with a payloadSpec and an interfaceType names its payload after the interface type, so a second register declaring the same interface type receives the type built for the first one, whatever its own element type, length, or members happen to be.

The C# target keeps a set of already emitted names and skips any repeat, in Device.tt. The Python target looks the payload up in a module-level list and reuses whatever it finds, in Python.cs. Neither compares the second register against the type it is handed.

What can go wrong

Two registers declaring the same interfaceType can differ in their payloadSpec members, in their element type, or in their declared length. In each case the second register is described by a type built for the first.

The C# target is partly self-correcting, because the conversion code is generated per register and assigns members by name, so a register whose members differ from the struct it inherits should reference a member that does not exist and fail to compile. Whether a mismatch only in element width also fails to compile has not been checked, so that half is reasoning from the templates rather than a measured result.

The Python target has no equivalent backstop. The emitted class is simply reused, and a register of a different width decodes against the wrong element type with no diagnostic.

Why this is worth recording now

It is latent rather than live. The only place in the published schemas where two registers share an interface type over a payloadSpec is Rgb0 and Rgb1 in device.behavior, and those are correct by construction, since Rgb1 is a YAML merge of the anchor on Rgb0 and cannot diverge from it.

What changes the calculus is that the runtime emitter in pyharp now mirrors this reuse deliberately, so both Python paths depend on the behavior being either correct or explicitly validated. See harp-tech/python#19 for that change and the reasoning behind matching the generator rather than adding a client-side check.

Possible resolutions

Validate in the generator, rejecting a repeated interface type whose register disagrees on element type, length, or members. This is the smaller change and keeps the check in one place per target, at the cost of every target implementing it independently.

Make the reuse an explicit schema declaration instead of something inferred from a repeated string. A named payload section in device.yml would let the schema carry the intent, so a generator validates a declared reference rather than guessing whether two matching strings mean the same type. A proposal for this is being prepared against the protocol repository and will be linked here once filed.

Related Issues

harp-tech/protocol#118
harp-tech/python#19

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions