Skip to content

Commit

Permalink
quoteArgs: handle empty, '$', and '&' strings
Browse files Browse the repository at this point in the history
This adds a fuzz test for quoteArgs and fixes the cases found by it:
empty strings and strings containing '$' and '&'.
  • Loading branch information
abhinav committed Feb 24, 2024
1 parent 334f6c1 commit 2b80b0a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 3 deletions.
4 changes: 1 addition & 3 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,15 +502,13 @@ func expandArgs(s *State, rawArgs [][]argFragment, regexpArgs []int) []string {
}

// quoteArgs returns a string that parse would parse as args when passed to a command.
//
// TODO(bcmills): This function should have a fuzz test.
func quoteArgs(args []string) string {
var b strings.Builder
for i, arg := range args {
if i > 0 {
b.WriteString(" ")
}
if strings.ContainsAny(arg, "'"+argSepChars) {
if len(arg) == 0 || strings.ContainsAny(arg, "&'$"+argSepChars) {
// Quote the argument to a form that would be parsed as a single argument.
b.WriteString("'")
b.WriteString(strings.ReplaceAll(arg, "'", "''"))
Expand Down
35 changes: 35 additions & 0 deletions engine_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package script

import (
"context"
"slices"
"testing"
)

func FuzzQuoteArgs(f *testing.F) {
state, err := NewState(context.Background(), f.TempDir(), nil /* env */)
if err != nil {
f.Fatalf("failed to create state: %v", err)
}

f.Add("foo")
f.Add(`"foo"`)
f.Add(`'foo'`)
f.Fuzz(func(t *testing.T, s string) {
give := []string{s}
quoted := quoteArgs(give)
cmd, err := parse("file.txt", 42, "cmd "+quoted)
if err != nil {
t.Fatalf("quoteArgs(%q) = %q cannot be parsed: %v", give, quoted, err)
}
args := expandArgs(state, cmd.rawArgs, nil /* regexpArgs */)

if !slices.Equal(give, args) {
t.Fatalf("quoteArgs failed to round-trip.\ninput:\n\t%#q\nquoted:\n\t%q\nparsed:\n\t%#q", give, quoted, args)
}
})
}
2 changes: 2 additions & 0 deletions testdata/fuzz/FuzzQuoteArgs/2abacd54f8b6b056
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
string("0\xa2$000")
2 changes: 2 additions & 0 deletions testdata/fuzz/FuzzQuoteArgs/5838cdfae7b16cde
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
string("")
2 changes: 2 additions & 0 deletions testdata/fuzz/FuzzQuoteArgs/e6019c3e89cc4df9
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
string("&")

0 comments on commit 2b80b0a

Please sign in to comment.