Skip to content

checkNoOOBPointers fuzz tests get TruncatedSource where they expect another error #144

Description

@thedavidmeister

testCheckNoOOBPointersHeaderTruncated and testCheckNoOOBPointersTrailingOffsetBytes in test/src/lib/bytecode/LibBytecode.checkNoOOBPointers.t.sol fail on some fuzz seeds with Error != expected error: TruncatedSource(...): the fuzzer reaches an input that trips TruncatedSource before the condition each test is pinning.

Reproduces on main with --fuzz-seed 0xeea1861ac7301d3cf09bfc4f3e99107bba6c76c3786908ba3b944f30770184d9 — 15 passed, 2 failed in that suite. Seed-dependent, so CI passes or fails by luck.

Triage question: whether the tests should exclude inputs that are truncated for the earlier reason, or whether the earlier check is firing where it should not.

Found while bounding the DuplicateFingerprint flake; separate suite, separate cause.

Activity

  1. thedavidmeister commented on Oct 2, 2026

    @thedavidmeister
    ContributorAuthor

    Decoded counterexample for testCheckNoOOBPointersHeaderTruncated at --fuzz-seed 0xeea1861ac7301d3cf09bfc4f3e99107bba6c76c3786908ba3b944f30770184d9:

    bytecode.length      89
    sourceCount          14   (re-read from bytecode[0] after conformBytecode)
    sourceRelativeStart  29
    offsetIndex          5
    nextOffset           24   (= offset[6])
    corruptOffset        21933
    

    The bound is doing what it intends: corruptOffset is far past nextOffset - 3, so when the backwards walk reaches index 5 its 4 byte header cannot fit before endCursor, which is sourcesStart + 24 by then. That is TruncatedHeader.

    The revert is TruncatedSource, so the walk is failing at an index above 5 — on an offset the test never corrupts. Either conformBytecode can emit a source whose end does not land on the next offset for some seeds, or the walk's expectation of it is wrong. Decoding the 89 byte bytecode and walking all 14 offsets is where this goes next.

    Not a regression: d6db9d7 (the most recent change to this file) only adds tests, 68 insertions and no deletions, so these two predate it and the flake is latent rather than new.

    One latent difference worth noting while here, not the cause at sourceCount = 14: this test computes 1 + sourceCount * 2 on a uint8, which overflows above 127, where the sibling testCheckNoOOBPointersSourceTruncated writes 1 + uint256(sourceCount) * 2.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions