Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/modernization.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ jobs:
run: |
go test ./...
go vet ./...
- name: Fuzz production Tell parsers
working-directory: native
run: |
go test -run=^$ -fuzz=FuzzTellSourceParserNoPanic -fuzztime=10s -parallel=2 ./internal/tell
go test -run=^$ -fuzz=FuzzTellExpressionParserNoPanic -fuzztime=10s -parallel=2 ./internal/tell
- name: Run Python tests
run: |
python -m compileall -q tell tests scripts
Expand Down
60 changes: 60 additions & 0 deletions native/internal/tell/parser_fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package tell

import "testing"

// FuzzTellSourceParserNoPanic checks that arbitrary UTF-8 or arbitrary-byte
// source is rejected with an error rather than crashing the production parser.
func FuzzTellSourceParserNoPanic(f *testing.F) {
seeds := []string{
"",
"Say 1.",
"Let answer be 2 plus 3.\nSay answer.",
"If true:\n Say \"ok\".\nEnd if.",
"To f with x:\n Give back f(x).\nEnd function.",
"Create a class called Box:\n When creating a Box:\n Remember 1 as this.value.\n End constructor.\nEnd class.",
"Tell object to open with \"wide\".",
"Call add with 1 and 2.",
"Use the module \"./helper.tell\" as helper.",
"Set items[-1] to 9.",
"Set the key \"name\" in data to \"Ada\".",
"Say \"unterminated",
"Say \xff\xfe\x00.",
"\r\n\t# comments\r\n",
"Otherwise if (",
}
for _, seed := range seeds {
f.Add(seed)
}
f.Fuzz(func(t *testing.T, source string) {
_, _ = parse(source, "fuzz.tell")
})
}

// FuzzTellExpressionParserNoPanic exercises the production expression lexer,
// Pratt parser, and AST construction independently of statement parsing.
func FuzzTellExpressionParserNoPanic(f *testing.F) {
seeds := []string{
"",
"1 + 2 * 3",
"not true or false",
"2 ** 3 ** 2",
"values[1:3].length",
"mapping[\"name\"]",
"f(1, right=2)",
"1 if condition else 0",
"\"escaped\\ntext\"",
"{1, 2, 2}",
"{\"name\": \"Ada\"}",
"1 / 0",
"(((((((((",
"\"unterminated",
"\xff\xfe\x00",
"λ + 1",
}
for _, seed := range seeds {
f.Add(seed)
}
f.Fuzz(func(t *testing.T, expression string) {
_, _ = parseTellExpressionAt(expression, 1, 1)
})
}
Loading