Repository navigation
fix(foundation): check every register_protocol_code key before registering any (#2268) - #2343
Conversation
|
Review: NEEDS CHANGES at
|
0ff7478 to
b621dc5
Compare
|
Amended |
|
Review: GOOD TO GO at
|
|
for |
|
Coverage: 91.58% (unit tier, Python 3.15,
Per-file detail: the |
b621dc5 to
79b88ee
Compare
|
Done for Pushed as |
|
i'd still prefer using |
|
Ruling noted: Type[ProtocolBase] with a type: ignore on the two abstract keys (Link, Internet). Dispatching the change. |
…ering any (#2268) register_protocol_code (and the code= class keyword) handed each {destination: key} pair straight to destination.register, so a member of another enum, e.g. {Frame: TransType.ICMP}, replaced the shipped LinkType.ETHERNET entry; and it registered targets as it flattened them, so a bad later target left the earlier ones registered. Flatten every target first, check each key with _check_code against the enum of the class owning its destination's __proto__ (_DESTINATION_KINDS), then register. A destination keeping a registry of its own (Loopback, IPX) is not checked. Tests: RegisterProtocolCodeKeyCheckTests snapshot and restore the real registries; the five rejection cases fail on main. A table-driven test pins every _DESTINATION_KINDS row against the real registrars, killing all 14 single-cell mutants (dropping a row, or flipping its number flag).
79b88ee to
3010e54
Compare
|
Pushed |
|
Review: GOOD TO GO at
|
|
Review: GOOD TO GO at
|
|
Ready to merge. Review: GOOD TO GO (Sonnet, round 4) at |
|
On hold for a design change: moving |
|
This merged before the class-attribute redesign I started above could land on it — opened as a follow-up instead: #2392. |
…tribute, not a module table (#2343) Problem: _DESTINATION_KINDS mapped a protocol class to the Enum registry _check_code validates its code against, found by walking the destination's MRO for whichever ancestor owns __proto__ and looking that owner up in the table. The pairing lived apart from the __proto__ it describes, and a new destination needed both a new __proto__ and a new row in a module dict elsewhere. Fix: each of the seven destination classes (Link, Internet, Frame, PCAPNG, TCP, UDP, SCTP) now declares its own __proto_key__ class attribute, alongside __proto__, pairing its Enum registry with whether a bare int is also valid. register_protocol_code reads it straight off the owner the MRO-walk already finds (via vars(), not getattr, so a class keeping a registry of its own -- Loopback, IPX -- does not inherit its parent's pairing). _check_code also takes the destination class explicitly now, so its error names which registry refused, not just which enum: "TCP: code must be ... not True" rather than "code must be ... not True". Every other call site of _check_code (register_ethertype, register_transtype, every option/parameter registrar) passes its own target the same way. Two call sites write into two registries keyed alike and pass one of the two as target, rather than checking twice for no behavioural difference: register_linktype (Frame and PCAPNG) names Frame; register_apptype (TCP and/or UDP, resolved after the check) names TCP. Test: test_a_registry_of_its_own_does_not_inherit_its_parent_pairing pins the Loopback/IPX case; test_a_rejection_names_the_destination_registry and test_every_rejection_names_the_destination_registry (24 subtests, one per call site) pin the new error prefix; test_every_destination_kind_row_is_enforced now walks every ProtocolBase subclass declaring __proto_key__ rather than a fixed dict's keys, so a new undeclared pairing is caught too.
make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix — bug fixDescription
Closes #2268.
register_protocol_codenow flattens every target and checks each key against its destination's enum before registering any — a wrong code can no longer replace a shipped entry, and a list that fails partway no longer leaves its earlier entries registered.origin/main. Passing on the rebased head.