Skip to content

exploreState rejects every valid numeric state #907

Description

@MicroMilo

Summary

Every repository-facing contract declares state numeric, including the native tracePcIndir boundary, but exploreState returns unless state is a string. Thus all valid calls are discarded while invalid strings reach the numeric native API.

Impact: Calls such as the maze example's jazzer.exploreState(hash(x, y), 0) never submit state feedback to libFuzzer, so the documented feature cannot guide exploration. Untyped calls with a string do reach a native function declared to require a number.

Code path

Checked against current main at commit 4c14e1bf63d82475ea057d6208e6f2eac87fa680.

  • packages/fuzzer/trace.ts:198-218
  • packages/fuzzer/addon.ts:56-62
  • packages/bug-detectors/DEVELOPMENT.md:113-118
  • examples/maze/fuzz.js:57-60

Steps to reproduce

Validation level: current HEAD supplemental dynamic witness reproduced.

node -e 'const fs=require("fs"); const source=fs.readFileSync("packages/fuzzer/trace.ts","utf8"); const match=source.match(/export function exploreState\(state: number, id: number\) \{[\s\S]*?\n\}/); if(!match) throw new Error("function not found"); const js=match[0].replace("export ","").replace("state: number","state").replace("id: number","id"); const calls=[]; const fn=Function("tracer",js+"; return exploreState")({tracePcIndir:(...args)=>calls.push(args)}); fn(7,11); console.log(JSON.stringify({input:[7,11],tracePcIndirCalls:calls}));'

Observed output:

{"input":[7,11],"tracePcIndirCalls":[]}

Neighboring control:

node -e 'const fs=require("fs"); const source=fs.readFileSync("packages/fuzzer/trace.ts","utf8"); const match=source.match(/export function exploreState\(state: number, id: number\) \{[\s\S]*?\n\}/); if(!match) throw new Error("function not found"); const js=match[0].replace("export ","").replace("state: number","state").replace("id: number","id"); const calls=[]; const fn=Function("tracer",js+"; return exploreState")({tracePcIndir:(...args)=>calls.push(args)}); fn("7",11); console.log(JSON.stringify({input:["7",11],tracePcIndirCalls:calls}));'

Control output:

{"input":["7",11],"tracePcIndirCalls":[[11,"7"]]}

Expected behavior

The documented/source-grounded contract should hold without the drift described above.

Actual behavior

exploreState rejects every contract-conforming numeric state while allowing strings through to the numeric tracer boundary.

Existing coverage

I checked the current issue and PR lists for overlapping titles/root-cause keywords before filing this. I did not find an item covering this same root cause.

Suggested fix

Correct exploreState's runtime guard to require a numeric state and numeric identifier.

Suggested tests

  • Add a regression test for the reproduction above.
  • Add a neighboring control assertion so the intended non-bug path remains covered.

Submitted with Codex.

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