You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(ipv6): to_dict() collapses repeated extension headers, so the dict rebuild silently shortens the packet #1453
Bug.Info.to_dict() keys IPv6 extension headers by name, so a second extension header of the same type overwrites the first. Rebuilding from the dict then silently produces a shorter packet. It does not raise.
Repro on #1452's head 2a6d4fba5; on main it is worse, since every extension header is lost:
Needs a decision: this fix has to change what the dumps contain, so I would like your call before a worker starts.
Options:
Suffix repeats. The second ipv6_opts becomes ipv6_opts_2, and so on. The dump layout is unchanged for every packet without a repeat, so real captures are unaffected (none of the 23 samples repeats a header).
Emit the chain as a list under one key, e.g. extension_headers: [...]. This is cleaner, but it changes the dump shape for every IPv6 packet that carries an extension header.
Leave the dict lossy and raise on rebuild.from_data(dict) would detect a chain it cannot recover and raise instead of shortening the packet. That breaks byte-exactness for the dict form, but no longer fails silently.
My recommendation is (1): it keeps the dict form byte-exact and changes nothing for packets that don't repeat a header.
Recorded: you suggested having to_dict() return a MultiDict so that repeated keys survive. I measured it on main (b14d676c5) with pcapkit.corekit.multidict.OrderedMultiDict, and it works.
OrderedMultiDict subclasses dict. items() yields the first value per key, and items(multi=True) yields every value in order.
json.dumps, and dictdumper's JSON and Tree writers, all see one value per key. The dump output is therefore unchanged for every packet, so none of the options I listed above is needed.
The dict rebuild can walk items(multi=True) to recover a repeated chain, so from_data(info.to_dict()) becomes byte-exact.
One consequence: dumps keep showing only the first of two repeated headers, exactly as they do today. Showing both is a separate change to the dumpers.
I'll go with this. It touches the same files as #1452 (infoclass.py, protocol.py, ipv6.py), so this is blocked until #1452 merges. A worker starts from main after that.
Correction to my earlier measurement above. I said the dumps would see one value per key. That held for dictdumper's writers called directly, which is what I tested. But pcapkit's own dumper object_hook (pcapkit/dumpkit/common.py) writes every OrderedMultiDict as a list of single-key entries, the #1263 handling. Returning one from to_dict() therefore turned every nested layer into an array: all 92 sample dumps changed. #1466 adds an InfoDict subclass that the dumper writes as a mapping, and all 92 dumps are byte-identical to main again.
Activity
JarryShaw commentedon Oct 9, 2026
Needs a decision: this fix has to change what the dumps contain, so I would like your call before a worker starts.
Options:
ipv6_optsbecomesipv6_opts_2, and so on. The dump layout is unchanged for every packet without a repeat, so real captures are unaffected (none of the 23 samples repeats a header).extension_headers: [...]. This is cleaner, but it changes the dump shape for every IPv6 packet that carries an extension header.from_data(dict)would detect a chain it cannot recover and raise instead of shortening the packet. That breaks byte-exactness for the dict form, but no longer fails silently.My recommendation is (1): it keeps the dict form byte-exact and changes nothing for packets that don't repeat a header.
JarryShaw commentedon Oct 9, 2026
what about return a
MultiDict?JarryShaw commentedon Oct 9, 2026
Recorded: you suggested having
to_dict()return aMultiDictso that repeated keys survive. I measured it onmain(b14d676c5) withpcapkit.corekit.multidict.OrderedMultiDict, and it works.OrderedMultiDictsubclassesdict.items()yields the first value per key, anditems(multi=True)yields every value in order.json.dumps, and dictdumper's JSON and Tree writers, all see one value per key. The dump output is therefore unchanged for every packet, so none of the options I listed above is needed.items(multi=True)to recover a repeated chain, sofrom_data(info.to_dict())becomes byte-exact.I'll go with this. It touches the same files as #1452 (
infoclass.py,protocol.py,ipv6.py), so this is blocked until #1452 merges. A worker starts frommainafter that.JarryShaw commentedon Oct 9, 2026
Unblocked: #1452 merged as
ca5f6dba1. A worker is on it now, on branchfix/1453-to-dict-multidict, using theOrderedMultiDictapproach recorded above.JarryShaw commentedon Oct 9, 2026
Correction to my earlier measurement above. I said the dumps would see one value per key. That held for dictdumper's writers called directly, which is what I tested. But pcapkit's own dumper
object_hook(pcapkit/dumpkit/common.py) writes everyOrderedMultiDictas a list of single-key entries, the #1263 handling. Returning one fromto_dict()therefore turned every nested layer into an array: all 92 sample dumps changed. #1466 adds anInfoDictsubclass that the dumper writes as a mapping, and all 92 dumps are byte-identical tomainagain.fix(corekit)!: to_dict() returns an InfoDict, so a repeated IPv6 exte…
fix(corekit)!: to_dict() returns an InfoDict, so a repeated IPv6 exte…