Skip to content

fix(protocols)!: parse a malformed IPv6 extension header as Raw (#2477) - #2480

Merged
JarryShaw merged 2 commits into
mainfrom
fix/2477-malformed-ext-raw
Oct 31, 2026
Merged

JarryShaw merged 2 commits into
mainfrom
fix/2477-malformed-ext-raw

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

Per RFC 8200 §4, a header whose dedicated parser raises (HOPOPT, Routing, Opts, MH, HIP, Frag, AH) is now Raw via beholder and ends the walk; IPv6._import_next_layer's IPv6_Ext fallback and __generic_ext_codes__ are removed. IPv6_Ext stays the parser for Shim6, so only Shim6 matches every member name. Docs (ipv6.py, ipv6_ext.py, ipv6-ext-entry-paths, the subclassing convention) and the tests pinning the fallback are updated; new tests cover malformed and truncated headers, Shim6, and byte-exact rebuilds. Stacked on #2464.

Closes #2477

@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) breaking Breaks public-facing behaviour or API (apply alongside the type label) review: running A cross-review is in flight against the current head - no verdict yet labels Oct 30, 2026
@github-actions github-actions Bot added this to the PyPCAPKit v1.5 milestone Oct 30, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES (Sonnet, c40071afb). Behaviour is right. Across 12,317 hand-built packets, every difference from the base is a former fallback now giving Raw. Samples match frame for frame, Shim6 is unchanged, and docs warnings equal the base's.

  • Regression: a malformed header is now logged twice. The walk breaks on hasattr(info, 'next') but keeps proto, so _decode_next_layer re-parses the same octets. Reuse the walk's Raw instead.
  • Breaking-change markers: add a versionremoved:: 1.6.0 for __generic_ext_codes__ and ! in the subject. Document that the IPv6_Ext.error field and read(error=) are no longer filled, and point readers to payload.info.error.
  • Stale prose: mh.py still says IPv6 substitutes IPv6_Ext for a failed MH (4 docstrings). Also stale: test_ipv6_ext_hint_unit.py, _has_fallback in test_short_read_roundtrip_unit.py, and "last two subtests" in test_mh_unit.py.
  • Missing test: none pins AH → Raw.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 30, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 30, 2026
RFC 8200 §4 has a node discard such a packet, so the walk stops at it.

- IPv6._import_next_layer: drop the IPv6_Ext fallback and __generic_ext_codes__.
- The Raw the walk stopped on is the upper layer, so its error is logged once.
- IPv6_Ext keeps Shim6, its only direct dispatch.
- IPv6_Ext.error and read(error=) are no longer filled; see info.error on Raw.
- Tests pin Raw for malformed and truncated HOPOPT/Routing/Opts/MH/HIP/AH.
- mh.py docstrings and the round-trip tests no longer describe the fallback.
@JarryShaw
JarryShaw force-pushed the fix/2477-malformed-ext-raw branch from c40071a to ad7cd10 Compare October 31, 2026 00:08
@JarryShaw JarryShaw changed the title fix(protocols): parse a malformed IPv6 extension header as Raw fix(protocols)!: parse a malformed IPv6 extension header as Raw (#2477) Oct 31, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Verified (ad7cd10a3): double-log fixed (2 records, down from 4; the remaining WARNING is beholder's own, flagged for decorators.py); breaking markers added and the subject carries !; stale MH prose rewritten; AH pinned. Sonnet review dispatched.

@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 31, 2026
@JarryShaw
JarryShaw changed the base branch from fix/2462-ipv6-ext-id to main October 31, 2026 00:18
@JarryShaw

Copy link
Copy Markdown
Owner Author

Base retargeted to main now that #2464 has merged. Still review: running; no other change.

@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES (Sonnet, ad7cd10a3). The double-log fix holds: one malformed HOPOPT now logs once plus beholder's WARNING, and the corpus is identical to base apart from one case.

  • Unexpected change: 45 of 26,205 cases now give NoPayload where base gives an empty Raw. Repro: a Routing header whose declared length overruns the Payload Length, with nothing after it. Cause: the reused next_ also captures a NoPayload built with length=None. Fix: reuse only when type(next_) is Raw. Or keep NoPayload on purpose and pin it.
  • Stale prose: test_mh_unit.py ~1466 still says the MH is "replaced by IPv6_Ext".

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 31, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Fixed (9dd653e74): overrun-Routing-with-nothing-after is Raw again (pinned by a new test), and the MH prose is corrected. Sonnet review dispatched.

@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Coverage: 94.50% (unit tier, Python 3.15, 69d6728d7, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 19677 133 2628 120 98.85%
pcapkit/corekit 2605 74 818 37 96.52%
pcapkit/dumpkit 281 3 100 3 98.43%
pcapkit/foundation 3070 24 1072 26 98.79%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 18050 194 4786 180 98.35%
pcapkit/toolkit 924 36 334 10 95.55%
pcapkit/utilities 502 7 144 5 98.14%
pcapkit/vendor 4449 1854 1020 167 55.11%

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

@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES (Sonnet, 9dd653e74). Behaviour verified: the overrun-Routing case is Raw, and 173k replayed cases differ only as the intended fallback-to-Raw change.

  • ipv6_ext.py read alias bullet (~L410-413) and the HOPOPT examples at ~L306-309 and ~L659-662 say IPv6_Ext supplies a failed header; only Shim6 does now.
  • unidiomatic-typecheck pragma: add a reason clause (exact-type is deliberate because Raw subclasses exist).
  • E305: one blank line missing before if __name__ in test_ipv6_exthdr_cut_rebuild_unit.py.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 31, 2026
@JarryShaw
JarryShaw force-pushed the fix/2477-malformed-ext-raw branch from 9dd653e to 9dd5d5f Compare October 31, 2026 01:53
@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 31, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES (Sonnet, 9dd5d5fcf). Prose fixes, pragma reason, E305, and the Raw-ends-walk behaviour are verified; 3 tests pass.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 31, 2026
- IPv6._decode_next_layer: a NoPayload the walk stops on was reused as the
  upper layer. An overrunning Routing header with nothing after it gave
  NoPayload where base gives an empty Raw. Reuse only a Raw.
- test_ipv6_ext_unit: pin that case as an empty Raw.
- test_mh_unit: over IPv6 the MH is replaced by Raw, not IPv6_Ext.
- Registry comments: IPv6_Ext is the generic parser, not a fallback.
@JarryShaw
JarryShaw force-pushed the fix/2477-malformed-ext-raw branch from 9dd5d5f to 69d6728 Compare October 31, 2026 02:11
@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 31, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO (Sonnet, 69d6728d7). The round is comment-only (AST-identical); the new block is 4 lines; 3 tests pass.

@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 Oct 31, 2026
@JarryShaw
JarryShaw merged commit 66a80c3 into main Oct 31, 2026
64 checks passed
@JarryShaw
JarryShaw deleted the fix/2477-malformed-ext-raw branch October 31, 2026 03:47
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 31, 2026
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaks public-facing behaviour or API (apply alongside the type label) fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

A malformed known IPv6 extension header should parse as Raw, not IPv6_Ext

1 participant