Fuzzing #38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Fuzzing | |
| on: | |
| schedule: | |
| # Run fuzzing weekly on Sunday at 2 AM UTC | |
| - cron: '0 2 * * 0' | |
| workflow_dispatch: | |
| inputs: | |
| target: | |
| description: 'Fuzzing target' | |
| required: false | |
| default: 'decoder' | |
| type: choice | |
| options: | |
| - decoder | |
| - encoder | |
| - encoderconfig | |
| - headers | |
| - markers | |
| - jp2 | |
| - icc | |
| iterations: | |
| description: 'Number of iterations' | |
| required: false | |
| default: '1000' | |
| jobs: | |
| fuzz: | |
| runs-on: windows-latest | |
| timeout-minutes: 120 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: [decoder, encoder, encoderconfig, headers, markers, jp2, icc] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup .NET 8 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Install SharpFuzz | |
| shell: pwsh | |
| run: dotnet tool install --global SharpFuzz.CommandLine | |
| - name: Build CoreJ2K.Fuzz | |
| shell: pwsh | |
| run: dotnet build CoreJ2K.Fuzz/CoreJ2K.Fuzz.csproj -c Release | |
| - name: Instrument CoreJ2K | |
| shell: pwsh | |
| run: | | |
| $tfm = (Select-Xml -Path CoreJ2K.Fuzz/CoreJ2K.Fuzz.csproj -XPath '//TargetFramework').Node.InnerText | |
| sharpfuzz "CoreJ2K.Fuzz/bin/Release/$tfm/CoreJ2K.dll" | |
| - name: Download seed corpus | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force -Path CoreJ2K.Fuzz/Testcases | Out-Null | |
| Invoke-WebRequest -Uri "https://github.com/uclouvain/openjpeg-data/raw/master/input/conformance/p0_01.j2k" -OutFile "CoreJ2K.Fuzz/Testcases/p0_01.j2k" -ErrorAction SilentlyContinue | |
| Invoke-WebRequest -Uri "https://github.com/uclouvain/openjpeg-data/raw/master/input/conformance/p0_02.j2k" -OutFile "CoreJ2K.Fuzz/Testcases/p0_02.j2k" -ErrorAction SilentlyContinue | |
| - name: Create findings directory | |
| shell: pwsh | |
| run: New-Item -ItemType Directory -Force -Path CoreJ2K.Fuzz/Findings | Out-Null | |
| - name: Run fuzzing | |
| shell: pwsh | |
| run: | | |
| Push-Location CoreJ2K.Fuzz | |
| pwsh -File Run-Fuzzing.ps1 -Target ${{ matrix.target }} -Quick | |
| Pop-Location | |
| continue-on-error: true | |
| - name: Upload findings | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fuzzing-findings-${{ matrix.target }} | |
| path: CoreJ2K.Fuzz/Findings/ | |
| if-no-files-found: ignore | |
| - name: Check for crashes | |
| shell: pwsh | |
| run: | | |
| $findingsPath = "CoreJ2K.Fuzz/Findings" | |
| if (-not (Test-Path -LiteralPath $findingsPath)) { | |
| Write-Host "No findings directory — nothing to check." | |
| exit 0 | |
| } | |
| $findings = Get-ChildItem -LiteralPath $findingsPath -Filter "crash_*" -ErrorAction SilentlyContinue | |
| if ($findings.Count -gt 0) { | |
| Write-Error "Fuzzing found $($findings.Count) crashes! Check artifacts." | |
| exit 1 | |
| } | |
| - name: Report findings | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| $findingsPath = "CoreJ2K.Fuzz/Findings" | |
| $crashes = if (Test-Path -LiteralPath $findingsPath) { (Get-ChildItem -LiteralPath $findingsPath -Filter "crash_*" -ErrorAction SilentlyContinue).Count } else { 0 } | |
| $hangs = if (Test-Path -LiteralPath $findingsPath) { (Get-ChildItem -LiteralPath $findingsPath -Filter "hang_*" -ErrorAction SilentlyContinue).Count } else { 0 } | |
| Write-Host "Fuzzing Results for ${{ matrix.target }}:" | |
| Write-Host " Crashes: $crashes" | |
| Write-Host " Hangs: $hangs" | |
| $summary = @" | |
| ## Fuzzing Results - ${{ matrix.target }} | |
| | Metric | Count | | |
| |--------|-------| | |
| | Crashes | $crashes | | |
| | Hangs | $hangs | | |
| "@ | |
| $summary | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append |