Skip to content

Fix IPv6 option round-tripping, tuple-valued option assignment, and stream/block validation edge cases #60

Description

@TheFoxy23

Summary

There are a few correctness issues in the parser/writer that can break valid usage patterns or produce confusing failures on malformed input:

  1. ipv6+prefix options seems do not round-trip correctly.
  2. Options.__setitem__ splits tuple-valued options into multiple values.
  3. The scanner docs say a stream only needs .read(), but parsing also requires .tell().
  4. Undersized block lengths are not rejected early and can lead to misleading downstream errors.

Problems

1. TYPE_IPV6_PREFIX encode/decode is broken

In pcapng/structs.py, the ipv6+prefix option path fails on Python 3:

  • Decode uses value[16] with struct.unpack(...), but value[16] is an int, not bytes.
  • Encode does pack_ipv6(value[0]) + value[1], which tries to concatenate bytes and int.

As a result, IPv6-prefix options such as if_IPv6addr cannot round-trip correctly.

2. Tuple-valued options are corrupted by Options.__setitem__

Options.__setitem__ currently treats any iterable that is not str/bytes as a list of repeated option values.

That breaks tuple-shaped option payloads such as:

options["typed_bytes"] = (7, b"data")

Instead of storing one logical value, it stores two values, which can trigger bogus repeated-option handling or malformed output.

3. Parsing requires .tell() even though the public contract only mentions .read()

FileScanner documentation says it accepts a file-like object providing .read(), but read_bytes_padded() also calls .tell().

This means read-only/non-seekable streams that implement .read() but not .tell() fail with AttributeError.

4. Invalid short block lengths are not rejected early

If a section header or block length is smaller than the minimum legal size:

  • Python may interpret a negative read size as "read the rest of the stream"
  • The parser can then fail later with StreamEmpty or TruncatedFile

This makes corruption harder to diagnose and can consume more input than intended before failing.

Expected behavior

  • ipv6+prefix options should decode and encode correctly.
  • Tuple-valued options should be preserved as a single option value.
  • Streams that provide .read() but not .tell() should still be readable when alignment tracking is not otherwise required.
  • Clearly invalid block lengths should raise CorruptedFile immediately.

Suggested fix

  • Fix TYPE_IPV6_PREFIX decode/encode handling in pcapng/structs.py
  • Make Options.__setitem__ preserve tuple-shaped single values and only treat explicit lists as replacement of multiple values
  • Make alignment checks tolerant of streams without .tell()
  • Add explicit minimum-length validation for section headers and blocks
  • Add regression tests for all of the above

Affected files

Notes

  • The malformed test006.ntar fixture should still fail; that behavior is expected.
  • It may also be worth replacing some public-path assert statements with explicit exceptions, since assert is removed under python -O.

I hope I didn't write some nonsense 🙃

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions