Repository navigation
203 lines (170 loc) · 5.42 KB
/
Copy pathfuzzing.yml
File metadata and controls
203 lines (170 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# 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