Skip to content

_missing_ in the four mh flag enums ends in return cls(value), so any non-member value recurses — including 0 #623

Description

@JarryShaw

_missing_ in the four Mobility Header flag enums ends in return cls(value) — the same constructor that just failed to find the value. That re-enters _missing_, unbounded, so any value not already a member raises RecursionError instead of resolving or failing cleanly.

The four modules

pcapkit/const/mh/binding_ack_flag.py
pcapkit/const/mh/binding_update_flag.py
pcapkit/const/mh/handover_ack_flag.py
pcapkit/const/mh/handover_initiate_flag.py

All four carry the identical body:

def _missing_(cls, value: 'int') -> 'BindingACKFlag':
    if not (isinstance(value, int) and 0 <= value <= 0xFF):
        raise ValueError('%r is not a valid %s' % (value, cls.__name__))
    return cls(value)

The range guard is fine. The final line is the defect: for an in-range value that is not a member, cls(value) calls _missing_ again with the same argument.

Note these four are the odd ones out — none of them has an extend_enum fallback, which every other const/ module's _missing_ uses to mint a member for an unregistered value. So there is nothing to break the cycle.

Measured

On origin/main (af1f771b9), CPython 3.14.7, tree asserted against the repository rather than the editable install:

defined values: [2, 4, 8, 16, 32, 64, 128]
F(0) -> RecursionError

The reachable value is 0, not some exotic in-range bit pattern. The seven members are the single bits 2 through 128, so no flags set — the most ordinary value an eight-bit flag field can carry — is not a member and recurses.

That is a more available trigger than the "undefined in-range flag bit" framing this was first reported under. My own first probes, F(0x02) and F(0x04), returned normally because they happen to be defined; it took enumerating the members to find that zero is the hole.

Reachability

Not established, and I am not claiming it. The reporting worker said it is "real and pre-existing but not wire-reachable", and I have not traced whether a parsed Mobility Header can present a zero flags octet to one of these four classes. Given 0 is the value at issue, that trace is worth doing before deciding the severity: a flags field with no bits set is not an unusual thing to appear on a wire.

If it is reachable, a RecursionError from library code on ordinary input is considerably worse than the ValueError the guard above it produces for out-of-range values.

Notes

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions