Skip to content

fix(corekit): a header cut inside a fixed-width field is zero-filled on parse and rebuilt at full width #1458

Closed

Description

@JarryShaw

Bug. When the capture ends inside a fixed-width field, the parse pads the missing octets with zeros (pcapkit/corekit/fields/field.py:586). Nothing records the shortfall, so the rebuild writes the field at its full width and the output is longer than the input.

Repro on main (b14d676c5):

e = bytes(12) + b'\x08'                            # Ethernet cut inside the EtherType
len(Ethernet.from_data(Ethernet(e, 13).info).data)  # 14, not 13

The #1454 edge-case suite hits this in about 300 cut cases: Ethernet, VLAN, ARP, RARP, L2TPv2, OSPF, IPX, IPv6, HIP, MH, AH, ESP, UDP and SCTP. It also shows up uncut, with an L2TPv2 Offset Size that points past the data and with a final SCTP chunk sent without its padding.

#1451 is the IPv6 extension-header instance of this same root cause. A fix in corekit would cover every family at once.

Found by #1454 (#1202).

Activity

  1. added
    fixPull requests that fix a defect (fix: subject prefix)
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 9, 2026
  2. JarryShaw commented on Oct 9, 2026

    @JarryShaw
    OwnerAuthor

    Needs a decision. There are two ways to make truncated headers round-trip, and they cover #1451 and this issue differently.

    1. Reject. A header whose declared length runs past the data raises ProtocolError, and the captured octets are kept as captured: IPv6-Ext inside an IPv6 chain, Raw elsewhere. This is what fix(protocols): a payload layer parsed from a short stream rebuilds default-filled octets #1170, fix(protocols): a declared length running past the data is accepted and zero-filled on rebuild #1325 and fix(ipv4,tcp): a header length declared past the data zero-fills the missing octets on rebuild #1404 already do. A worker has this ready for IPv6 extension headers (branch fix/1451-truncated-ext-header, 96488354b). All 12 header kinds then rebuild exactly at every cut offset, for example Routing type 0 going from 32 failures to 0. The cost: a truncated header is no longer decoded, and IPv6_Route(short) raises. That is breaking.
    2. Record the short read in corekit. Fields would note how many octets they actually read, instead of zero-filling (corekit/fields/field.py:586, strings.py:374), and pack would write back only that many. Every family keeps decoding a truncated header, and fix(corekit): a header cut inside a fixed-width field is zero-filled on parse and rebuilt at full width #1458's roughly 300 cases across Ethernet, VLAN, ARP, IPX, IPv6, HIP, MH, AH, ESP, UDP and SCTP close together. It is a larger change, but in one place.

    My recommendation is (2): it fixes the root cause once and loses no decoded detail. If you prefer (2), the #1451 branch would be dropped, because (2) makes its rejection redundant.

  3. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    and removed
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 9, 2026
  4. JarryShaw commented on Oct 9, 2026

    @JarryShaw
    OwnerAuthor

    yea (2) sounds about right

  5. JarryShaw commented on Oct 9, 2026

    @JarryShaw
    OwnerAuthor

    Recorded: option (2) it is. Corekit fields will record a short read instead of zero-filling it, and pack will write back only the octets actually read, so every family keeps decoding a truncated header and rebuilds it exactly. The same worker is on it now, starting from main; the PR will close both this issue and #1451. The reject-based branch fix/1451-truncated-ext-header gets dropped.

  6. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 9, 2026
  7. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 9, 2026
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

    fixPull requests that fix a defect (fix: subject prefix)

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions