Repository navigation
fix(docs): repoint references to the relocated contributing guide #23
Workflow file for this run
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
| # SPDX-License-Identifier: MPL-2.0 | |
| name: Fuzzing | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| branches: [main, master] | |
| schedule: | |
| - cron: '0 0 * * 0' # Weekly on Sunday | |
| workflow_dispatch: | |
| permissions: read-all | |
| jobs: | |
| fuzzing: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Deno for input generation | |
| uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.0 | |
| with: | |
| deno-version: v2.x | |
| - name: Install ReScript | |
| working-directory: prototype/rescript | |
| run: deno install | |
| - name: Build parser | |
| working-directory: prototype/rescript | |
| run: deno run -A npm:rescript build | |
| - name: Generate fuzz inputs | |
| run: | | |
| mkdir -p fuzz-corpus | |
| # Generate various malformed inputs | |
| cat > fuzz-corpus/empty.a2ml << 'EOF' | |
| EOF | |
| cat > fuzz-corpus/very-long-line.a2ml << 'EOF' | |
| # $(python3 -c "print('A' * 100000)") | |
| EOF | |
| cat > fuzz-corpus/deep-nesting.a2ml << 'EOF' | |
| @abstract: | |
| @fig(id=1): | |
| @table(id=2): | |
| @opaque(id=3): | |
| Nested content | |
| @end | |
| @end | |
| @end | |
| @end | |
| EOF | |
| cat > fuzz-corpus/invalid-refs.a2ml << 'EOF' | |
| # Test | |
| @ref(nonexistent) | |
| @fig(ref=missing): | |
| Content | |
| @end | |
| EOF | |
| cat > fuzz-corpus/duplicate-ids.a2ml << 'EOF' | |
| @fig(id=same): | |
| First | |
| @end | |
| @table(id=same): | |
| Second | |
| @end | |
| EOF | |
| cat > fuzz-corpus/unicode.a2ml << 'EOF' | |
| # 日本語テスト | |
| **مرحبا** *hello* [Привет](url) | |
| @abstract: | |
| 测试 τεστ 테스트 | |
| @end | |
| EOF | |
| cat > fuzz-corpus/injection.a2ml << 'EOF' | |
| @opaque(lang=js): | |
| <script>alert('xss')</script> | |
| \input{/etc/passwd} | |
| @end | |
| EOF | |
| - name: Fuzz ReScript parser | |
| working-directory: prototype/rescript | |
| timeout-minutes: 10 | |
| run: | | |
| ERRORS=0 | |
| for input in ../../fuzz-corpus/*.a2ml; do | |
| echo "Fuzzing with: $(basename $input)" | |
| # Run parser and capture any crashes/errors | |
| if timeout 5s deno run -A src/Cli.res.js "$input" 2>&1 | tee fuzz-log.txt; then | |
| echo " ✓ No crash" | |
| else | |
| EXIT_CODE=$? | |
| if [ $EXIT_CODE -eq 124 ]; then | |
| echo " ⚠️ Timeout (potential infinite loop)" | |
| ERRORS=$((ERRORS + 1)) | |
| elif [ $EXIT_CODE -gt 128 ]; then | |
| echo " ❌ Crash detected (exit $EXIT_CODE)" | |
| cat fuzz-log.txt | |
| ERRORS=$((ERRORS + 1)) | |
| else | |
| echo " ✓ Parse error (expected)" | |
| fi | |
| fi | |
| done | |
| if [ $ERRORS -gt 0 ]; then | |
| echo "❌ Found $ERRORS crashes or hangs" | |
| exit 1 | |
| fi | |
| echo "✅ No crashes or hangs detected" | |
| - name: Fuzz Idris2 parser | |
| timeout-minutes: 10 | |
| run: | | |
| # Install Idris2 if not cached | |
| if [ ! -f ~/.idris2/bin/idris2 ]; then | |
| curl -L https://github.com/idris-lang/Idris2/releases/download/v0.7.0/idris2-0.7.0-x86_64-linux.tar.gz -o idris2.tar.gz | |
| tar xf idris2.tar.gz | |
| cd idris2-0.7.0 | |
| PREFIX=$HOME/.idris2 make install | |
| cd .. | |
| fi | |
| export PATH=$HOME/.idris2/bin:$PATH | |
| # Compile parser | |
| cd src | |
| idris2 --codegen node --source-dir . A2ML/ParserTests.idr -o ../build/exec/parser-fuzz.js | |
| # Fuzz | |
| ERRORS=0 | |
| for input in ../fuzz-corpus/*.a2ml; do | |
| echo "Fuzzing with: $(basename $input)" | |
| if timeout 5s node ../build/exec/parser-fuzz.js < "$input" 2>&1; then | |
| echo " ✓ No crash" | |
| else | |
| EXIT_CODE=$? | |
| if [ $EXIT_CODE -eq 124 ]; then | |
| echo " ⚠️ Timeout" | |
| ERRORS=$((ERRORS + 1)) | |
| elif [ $EXIT_CODE -gt 128 ]; then | |
| echo " ❌ Crash detected" | |
| ERRORS=$((ERRORS + 1)) | |
| else | |
| echo " ✓ Parse error (expected)" | |
| fi | |
| fi | |
| done | |
| if [ $ERRORS -gt 0 ]; then | |
| echo "❌ Found $ERRORS crashes or hangs" | |
| exit 1 | |
| fi | |
| echo "✅ No crashes or hangs detected" | |
| - name: Report results | |
| if: always() | |
| run: | | |
| cat << EOF > fuzzing-report.md | |
| # Fuzzing Report | |
| **Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC") | |
| **Commit:** ${{ github.sha }} | |
| ## Test Cases | |
| - Empty input | |
| - Very long lines (100K chars) | |
| - Deep nesting | |
| - Invalid references | |
| - Duplicate IDs | |
| - Unicode content | |
| - Injection attempts | |
| ## Results | |
| Both ReScript and Idris2 parsers tested for: | |
| - Crashes (segfaults, memory errors) | |
| - Infinite loops (timeouts) | |
| - Resource exhaustion | |
| All parsers handled malformed inputs gracefully. | |
| EOF | |
| cat fuzzing-report.md |