Repository navigation
fix(schema): Schema.pack keeps option padding, SchemaField spans and iterated keys (#1289, #1291, #1292) - #1374
Conversation
|
Cross-review verdict on #1292 is only half fixed. Parse → pack is now byte-exact ( Held up:
Also say in the body: a |
…iterated keys - pack: an OptionField records the part of its declared area the packed options leave unfilled as __option_padding__, the mirror of unpack, so TCP and IPv4 rebuild to the length their header declares (#1289). - __getitem__: serves every key __iter__ yields, including values a post_process stores, so dict(schema) no longer raises KeyError (#1291). - pack: a SchemaField packs its whole declared span, re-emitting the octets its nested schema left unread when the unpack buffer still holds them and zero-filling otherwise (refs #1292). A schema rebuilt through from_data still zero-fills them; that remainder is #1380.
96b32e3 to
9d920e2
Compare
|
Round-2 verdict on |
|
Coverage: 88.98% (unit tier, Python 3.14,
Per-file detail: the |
Please follow the guide below
make pylint,make mypy,make isort) — pylint/mypy/isort run onschema.pywith the Makefile flags; no finding thatorigin/maindoes not already havemake testpasses, and a test case covers the change — the modules listed below, not the whole suiteWhat is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Closes #1289
Closes #1291
Refs #1292 (the parse ->
from_dataremainder is #1380)All three still reproduced on
13aa677be(after #1331). Fixes, all inprotocols/schema/schema.py:packsets__option_padding__after anOptionFieldto the part of the declared area left unfilled (the mirror ofunpack). D3:tcp.pcap#144->43,many_interfaces#24/#5244->43, IPv4 24->22 -> all equal.__getitem__serves every key__iter__yields. D5:dict(TSOption)KeyError -> works.SchemaFieldpacks its whole declared span. Unread octets are re-emitted from the unpack buffer, otherwise zero-filled. D6:0302eeee04 -> 030204->0302eeee04. Afrom_dict(to_dict())rebuild gives0302000004: width kept, octets zeroed, because the dict has no slot for them.Protocol.from_datahits the same case, so the owner's parse ->from_dataround trip still zero-fills; that is fix(schema): a SchemaField's unread octets are lost through from_data, so a direct SchemaField rebuilds zero-filled #1380, which also updatestest_schema_field_keeps_declared_width(now commented as such). Fields behind aSwitchFieldare not changed: the PCAP-NG block selector declares the rest of the stream as its span. No fixture capture has a non-PCAP-NGSchemaFieldremainder (measured).Contract changes: a
bytesvalue shorter than aSchemaField's span now pads to the span (030704becomes0307000004), a behaviour change for user schemas.'x' in schemaandschema.get('x')now seepost_processvalues.make()now pads an option area its options leave short.Tests: new
tests/protocols/schema/test_schema_roundtrip_unit.py6 passed; withorigin/main'sschema.py5 fail (the sixth is a guard that builtins stay unreadable).run_unittest_leg.py protocols/internet529 tests OK;protocols --exclude protocols/internet927 tests OK;tests/project389 passed, 1 skipped;test_schema_unit.py16 passed;test_option_roundtrip_unit.py6 passed. Per-frameinfoover 1588 frames in 22 captures is identical toorigin/main.