Skip to content

fix(protocols): rebuild a cut standalone header with the values its parse read (#2761) - #2767

Merged
JarryShaw merged 1 commit into
mainfrom
fix/2761-cut-ext-header-values
Nov 4, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/2761-cut-ext-header-values

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • fix — corrects a defect

Description of your pull request and other information

A standalone header cut short rebuilt to exact octets, but from_data(info).info != info. unpack() kept the header that make() had built, so read() returned the values make() filled in past the cut: zeroed Reserved octets, an invented PadN, and nested schemas at full width.

  • Protocol.__post_init__ now drops that built header, so unpack parses the captured octets the same way a parse does. A payload rebuilt inside _make_payload keeps its built header, since only its octets are used. The re-parse runs with warnings held, and the data model's __short_read__ is set afterwards. Only method bodies change.
  • Fixed: IPv6-Route reserved, IPv6-Frag reserved_octet, and HOPOPT/IPv6-Opts options. The sweep also found and fixed MH options and msg_reserved, and IGMPv3 length.
  • test-coverage.rst (Round-Trip Invariants) now states the rule.
  • The two new modules fail on main (166 and 18 failures) and pass here.
  • Still open: IPv6_Ext length at cut 1. The data model doesn't record which width the parse was given. A test table records the gap, and fix(protocols): a cut standalone IPv6 extension header rebuilds with values its parse did not read #2761 carries the decision.

Part of #2761

…arse read (#2761)

from_data rebuilt a header the capture cut short by reading the header make()
built, cut back to the octets captured: its zero-filled Reserved octets, the
PadN padding an option area out, a nested schema at full width. The octets
matched; the values did not.

- Protocol.__post_init__ drops that header, so unpack parses the octets back,
  except in a payload _make_payload rebuilds, which gives only its octets.
- Protocol.unpack parses it as quietly as the made header was read, and gives
  it the data model's __short_read__ before read.
- test-coverage.rst: a round trip reproduces the parsed values too.

The new sweep and hand-picked tests fail without the fix; IPv6_Ext's length
at cut 1 is recorded as still divergent.
@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) review: running A cross-review is in flight against the current head - no verdict yet labels Nov 4, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Nov 4, 2026
@github-actions github-actions Bot added this to the PyPCAPKit v1.6 milestone Nov 4, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 804d31878 (Sonnet cross-review, and my own run of the new tests)

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Coverage: 94.45% (unit tier, Python 3.15, 804d31878, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 106 4 20 2 95.24%
pcapkit/const 20918 175 2908 156 98.57%
pcapkit/corekit 2895 76 930 37 96.84%
pcapkit/dumpkit 286 3 102 3 98.45%
pcapkit/foundation 3507 27 1216 32 98.75%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 22772 155 5922 127 99.00%
pcapkit/toolkit 961 26 342 8 96.62%
pcapkit/utilities 559 7 150 5 98.31%
pcapkit/vendor 5590 2286 1280 214 55.75%

Per-file detail: the coverage-html artifact of this run.

@JarryShaw
JarryShaw merged commit e18d66e into main Nov 4, 2026
72 checks passed
@JarryShaw
JarryShaw deleted the fix/2761-cut-ext-header-values branch November 4, 2026 17:16
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Nov 4, 2026
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Nov 4, 2026
JarryShaw added a commit that referenced this pull request Nov 4, 2026
- #2766 (Fixed): a cut list of plain values ends with the data, where 1.5.x
  read zero values past the cut (a cut Type 0 Routing header, measured on
  v1.5.1), into the ListField entry; IGMPv3's sources and the Query's
  num_sources, into the IGMP entry.
- #2767: a cut header rebuilt on its own reads back its parsed values, a
  regression of the 1.6.0 rebuild path, into the cut-header Fixed entry; the
  round-trip test rule, into the conventions entry.
- #2764: SSLv2, TLS and DTLS records rebuild from their to_dict(), into the
  TLS/DTLS Added entry, as those classes never shipped.
- #2765: the further member reorders and guard rules, into the member-order
  entry, which records the earlier #2490 reorders.
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
JarryShaw added a commit that referenced this pull request Nov 4, 2026
- #2770: 1.5.1's Protocol.__init_subclass__ already registered a subclass
  as it was defined. The entry names what changed, measured on a v1.5.1
  export: an abstract subclass is skipped, where 1.5.x registered it, and a
  name clash keeps the existing entry and warns, where 1.5.x replaced it and
  warned that it was overwriting.
- #2767: drops "length", since IPv6_Ext's length at cut 1 is still open on
  #2761.
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
JarryShaw added a commit that referenced this pull request Nov 4, 2026
…2761) (#2777)

A cut header's rebuild was read at the width make() packs, so an IPv6_Ext cut at
one octet, whose length is the width its parse was given, rebuilt with a length
of two.

- Data: a __short_width__ key, carried by to_dict() and left out of repr and the
  dumps, records the length the parse read a cut header at.
- keep_short_read records it beside __short_read__, from the length each layer
  base passes on; Protocol.from_data reads the rebuild at it.
- It replaces Protocol._uncaptured and _short_of_header: read at its parse's
  width, the rebuild leaves its next layer the length its parse did.
- The #2767 sweep drops its known gap; the IGMPv3 direct-vs-IPv4 tests set the
  width aside, each read at its own; utilities-or-corekit.rst records the ruling.

The new tests fail without the fix; every sample capture rebuilds unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant