udf-forensic 0.2.4

Forensic-grade, from-scratch UDF (ECMA-167 / OSTA) reader and tamper analyzer — volume recognition, partition maps (physical/virtual/sparable/metadata), File Entry and directory (FID) traversal, file data, plus graded findings (tag CRC/checksum, orphan File Entries, slack, file-after-volume) over any Read + Seek source
Documentation
name: Fuzz (scheduled)

# Deep, time-boxed fuzzing of every target on a schedule (and on demand). PR CI
# is not the place for long fuzz runs; this runs each target for 10 minutes and
# uploads any crash artifact.
on:
  schedule:
    - cron: "0 4 * * 1" # Mondays 04:00 UTC
  workflow_dispatch:

permissions:
  contents: read

jobs:
  fuzz:
    name: Fuzz ${{ matrix.target }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        target: [detect, parse_state, read_fe, read_dir]
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - uses: dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2 # nightly
        with:
          toolchain: nightly
          components: rust-src
      - run: cargo install cargo-fuzz
      - name: Seed corpus from committed images
        run: |
          mkdir -p "fuzz/corpus/${{ matrix.target }}"
          cp tests/data/*.img "fuzz/corpus/${{ matrix.target }}/" 2>/dev/null || true
      - name: Fuzz ${{ matrix.target }} (10 min)
        run: cargo +nightly fuzz run "${{ matrix.target }}" -- -max_total_time=600 -rss_limit_mb=4096
      - name: Upload crash artifacts
        if: failure()
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: fuzz-crash-${{ matrix.target }}
          path: fuzz/artifacts/
          if-no-files-found: ignore