Skip to content

frame.py:199 seeds packet['bytesorder'] where readers expect 'byteorder', and no big-endian PCAP fixture exists to catch it #605

Description

@JarryShaw

pcapkit/protocols/misc/pcap/frame.py:199 seeds packet['bytesorder'] where every reader expects packet['byteorder']. The same file spells it correctly eleven lines earlier.

The two sites

pcapkit/protocols/misc/pcap/frame.py:176      packet['byteorder']  = self._ghdr.magic_number.byteorder
pcapkit/protocols/misc/pcap/frame.py:199      packet['bytesorder'] = self._ghdr.magic_number.byteorder

Same value, same source, two spellings, in one file. Readers use byteorder — pcapkit/protocols/misc/pcapng.py and pcapkit/protocols/schema/misc/pcapng.py each consult it twice.

Effect

The #594 worker reports that a big-endian classic PCAP crashes outright as a result, and that the one-character fix resolves it.

I have confirmed the typo by reading both lines. I have NOT reproduced the crash, and neither did the worker: it states plainly that no big-endian .pcap fixture exists in the repository, so the failure path is untested. That absence is itself worth noting — a byte-order branch with no fixture is a branch nothing exercises.

Notes

Activity

  1. JarryShaw commented on Sep 22, 2026

    @JarryShaw
    OwnerAuthor

    Adding the mechanism, which neither I nor the original reporter had, and which explains why no test catches this.

    The consumer is pcapkit/protocols/schema/misc/pcap/frame.py:29, inside byteorder_callback:

    field._byteorder = packet.get('byteorder', sys.byteorder)

    and that callback is attached to four fields — ts_sec (:39), ts_usec (:41), incl_len (:43) and orig_len (:45).

    So because pcapkit/protocols/misc/pcap/frame.py:199 writes packet['bytesorder'] rather than 'byteorder', the .get() never finds the key and always falls through to sys.byteorder — the host's native order rather than the capture's declared order.

    That is why nothing catches it: on a little-endian host reading a little-endian capture, the fallback coincidentally produces the right answer for every field. Every fixture and every CI runner in this repository is little-endian, so the wrong code path has always produced correct results.

    The asymmetry is also clear evidence of a copy-paste slip rather than an intentional second key: the sibling pack() method at frame.py:176 spells packet['byteorder'] correctly.

    Consequence beyond the crash. A big-endian classic PCAP read on a little-endian host would not merely crash — where it does not crash, ts_sec, ts_usec, incl_len and orig_len would all be byte-swapped, and incl_len in particular feeds length arithmetic. So this is a correctness issue and not only an availability one.

    This reinforces the point already in this issue: a fix needs a big-endian fixture, otherwise the corrected code path remains as untested as the broken one. examples/generators/make_samples.py is where sample captures are produced.

    Verified by reading both writers and the consumer on origin/main (13a75dfcd). The crash itself remains unreproduced — no big-endian .pcap exists to reproduce it with.

  2. added
    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)
    on Sep 22, 2026
  3. added this to the 1.5 milestone on Oct 6, 2026
  4. moved this to Done in PyPCAPKiton Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions