Repository navigation
fix(protocols): from_data keeps declared lengths on truncated captures - #1166
Merged
Merged
Conversation
IPv4, IPv6 and UDP computed their length field from the payload `make()` was handed, so a `from_data` rebuild of a capture cut short by the snaplen wrote the recorded length instead of the declared one -- 1186 became 82 on `big_endian.pcap` frame 3, and the UDP length 0x048e became 0x003e. Each `make()` now takes the length explicitly (`total_length` for IPv4 and UDP, `payload_length` for IPv6) and writes it as given; `_make_data` hands over the parsed one. Omitting it computes the length as before, so a plain `IPv4(payload=...)` is unchanged. Closes #1155
Contributor
|
Coverage: 88.87% (unit tier, Python 3.14,
Per-file detail: the |
Owner
Author
|
Cross-review verdict on
|
JarryShaw
added a commit
that referenced
this pull request
Oct 7, 2026
- 4 new 1.5.0 entries: HTTP/2 sample stream identifiers (#1161), TCP option re-padding (#1163, breaking), format='pcap' output (#1164), declared lengths on truncated captures (#1166, breaking) - extend the PCAP Header (#1159), HIP (#1160) and from_data round-trip (#1162) entries rather than duplicating them - regenerate CHANGELOG.md with util/changelog_md.py - process.rst: entry-count pin re-measured, 189 -> 193 tests/project: conventions_doc_claims, changelog_md and documentation_claims pass; changelog_md.py --check is in step.
This was referenced Oct 7, 2026
Merged
Closed
JarryShaw
added a commit
that referenced
this pull request
Oct 7, 2026
) `_make_data` returned the parsed Length under `length`, which `ProtocolBase.__init__` consumes as the parse length, so it never reached `make()` and the rebuild cleared `L` and omitted the Length octets. `make()` now takes it as `total_length`, as #1166 did for IPv4 and UDP, and `_make_data` passes it under that key. `test_link_unit` called `make(length=20)` directly and is updated to the new keyword. All 24 T/L/S/O(+pad) combinations now round-trip. Closes #1172
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
make pylint,make mypy,make isort) — not runmake testpasses, and a test case covers the change — ran the new module plustest_ipv4_unit,test_ipv6_unit,test_tcp_udp_unit,test_udp_runtime,tests/projectdocs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A, added centrally after the waveWhat is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Closes #1155, per the maintainer's ruling: on a truncated capture
from_datakeeps each length field as it was on the wire.IPv4.make,UDP.makeandIPv6.makecomputed the length from the payload handed to them, so a rebuild wrote the recorded length. Each now takes it explicitly —total_lengthfor IPv4/UDP,payload_lengthfor IPv6 — and_make_datapasses the parsed one through. Omitting it computes as before, soIPv4(payload=...)is unchanged.Public
make()behaviour: additive only. A new optional keyword, appended beforepayload, with the old computation as its default; no existing call changes its output. Not abreakingchange._make_datagains a key, which is why three existing hand-built data stubs needed the field added (test_ipv4_unit,test_ipv6_unit,test_tcp_udp_unit— the UDP edit is two lines and does not touch the TCP options assertions).Probe,
X.from_data(x.info).data == x.dataon the truncated frames:big_endian.pcap#3 IPv4450004a2…→45000052…big_endian.pcap#3 UDP048e→003ebig_endian_nanosecond.pcap,little_endian.pcapOver all of
examples/captures/, header-isolated: IPv4 mismatches 4 → 1, UDP 8 → 1, IPv6 0 → 0, with no new mismatches. The one remaining case istest.pcapngframe 3, cut inside the IPv4 header (18 of 20 octets), so UDP was parsed from zero bytes and its whole header is fabricated — a separate defect, not this one; the declared 300 is now preserved and the rebuilt prefix matches the 18 captured octets.Reverting the fix:
11 failed, 4 passed, 39 subtests passed. With it:6 passed, 48 subtests passed.