Skip to content

feat: input validation - Validate trait, Valid<E> extractor and #[derive(Validate)] #333

feat: input validation - Validate trait, Valid<E> extractor and #[derive(Validate)]

feat: input validation - Validate trait, Valid<E> extractor and #[derive(Validate)] #333

Workflow file for this run

name: Fuzz
on:
pull_request:
branches: ["main"]
schedule:
- cron: "17 3 * * *"
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
ASAN_OPTIONS: quarantine_size_mb=1:malloc_context_size=0
jobs:
# The pinned nightly lives in .github/fuzz-nightly rather than in this file's `env:`
# block. GITHUB_TOKEN has no `workflows` permission scope, so the bump-fuzz-nightly bot
# cannot push an edit to a file under .github/workflows/; keeping the pin in a plain
# file lets the monthly bump PR be opened with the default token.
pin:
runs-on: ubuntu-latest
outputs:
toolchain: ${{ steps.read.outputs.toolchain }}
steps:
- uses: actions/checkout@v4
- name: Read the pinned nightly
id: read
run: |
toolchain="$(grep -vE '^[[:space:]]*(#|$)' .github/fuzz-nightly | head -n1 | tr -d '[:space:]')"
if [ -z "$toolchain" ]; then
echo "::error::.github/fuzz-nightly contains no toolchain line"
exit 1
fi
echo "toolchain=$toolchain" >> "$GITHUB_OUTPUT"
echo "Pinned nightly: $toolchain"
fuzz_build:
runs-on: ubuntu-latest
needs: pin
env:
RUST_NIGHTLY: ${{ needs.pin.outputs.toolchain }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: ${{ env.RUST_NIGHTLY }}
- name: Install cargo-fuzz
run: cargo install cargo-fuzz --locked
- name: Sync fuzz lockfile (minimal relock, preserves pinned deps)
# NOT --locked: the fuzz crate is a separate workspace, so its Cargo.lock is not
# auto-updated when a normal PR bumps a dependency version in the main manifests.
# A strict --locked gate therefore breaks on every such bump. Instead we seed from
# the committed fuzz/Cargo.lock and let cargo minimally update only the out-of-range
# entries. Seeding from the committed lock keeps alloc-no-stdlib pinned at 2.0.4,
# which is what prevents the 2.0.4/3.0.0 split that breaks brotli on a fresh resolve.
run: cargo +${{ env.RUST_NIGHTLY }} metadata --manifest-path fuzz/Cargo.toml --format-version 1 > /dev/null
- name: Build fuzz targets
run: cargo +${{ env.RUST_NIGHTLY }} fuzz build
fuzz_smoke:
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
needs: [pin, fuzz_build]
env:
RUST_NIGHTLY: ${{ needs.pin.outputs.toolchain }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: ${{ env.RUST_NIGHTLY }}
- name: Install cargo-fuzz
run: cargo install cargo-fuzz --locked
- name: Smoke run router
run: cargo +${{ env.RUST_NIGHTLY }} fuzz run fuzz_router_match -- -max_len=512 -max_total_time=45 -rss_limit_mb=512
- name: Smoke run query
run: cargo +${{ env.RUST_NIGHTLY }} fuzz run fuzz_query_decode -- -max_len=1024 -max_total_time=45 -rss_limit_mb=512
fuzz_nightly:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
needs: [pin, fuzz_build]
env:
RUST_NIGHTLY: ${{ needs.pin.outputs.toolchain }}
strategy:
fail-fast: false
matrix:
include:
- target: fuzz_router_match
max_len: 512
- target: fuzz_query_decode
max_len: 1024
- target: fuzz_extractor_typed
max_len: 4096
- target: fuzz_openapi_gen
max_len: 256
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: ${{ env.RUST_NIGHTLY }}
- name: Install cargo-fuzz
run: cargo install cargo-fuzz --locked
- name: Nightly fuzz run
run: cargo +${{ env.RUST_NIGHTLY }} fuzz run ${{ matrix.target }} -- -max_len=${{ matrix.max_len }} -max_total_time=300 -rss_limit_mb=512