perf(sandbox): compile command-substitution regexps once
hasCommandSubstitution recompiled its three regexps with regexp.MustCompile on every call, and ValidateArgs calls it once per argument — so validating an N-arg command compiled 3N patterns. Hoist them to a package-level slice compiled once at init. Behavior is unchanged (same patterns); covered by the existing TestScriptValidator_ValidateArgs / ValidateAll tests. Benchmark, ValidateArgs with 8 args (-benchmem): before: 16374 ns/op, 40142 B/op, 505 allocs/op after: 2092 ns/op, 32 B/op, 1 allocs/op Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -217,15 +217,18 @@ func (v *ScriptValidator) hasShellOperators(s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Command-substitution patterns, compiled once. hasCommandSubstitution runs
|
||||
// per argument in ValidateArgs, so recompiling these on every call wasted work
|
||||
// proportional to the argument count.
|
||||
var commandSubstitutionPatterns = []*regexp.Regexp{
|
||||
regexp.MustCompile(`\$\([^)]+\)`), // $(command)
|
||||
regexp.MustCompile("`[^`]+`"), // `command`
|
||||
regexp.MustCompile(`\$\{[^}]*\$\(`), // ${...$(command)
|
||||
}
|
||||
|
||||
// hasCommandSubstitution checks for command substitution patterns
|
||||
func (v *ScriptValidator) hasCommandSubstitution(s string) bool {
|
||||
patterns := []*regexp.Regexp{
|
||||
regexp.MustCompile(`\$\([^)]+\)`), // $(command)
|
||||
regexp.MustCompile("`[^`]+`"), // `command`
|
||||
regexp.MustCompile(`\$\{[^}]*\$\(`), // ${...$(command)
|
||||
}
|
||||
|
||||
for _, p := range patterns {
|
||||
for _, p := range commandSubstitutionPatterns {
|
||||
if p.MatchString(s) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -359,3 +359,12 @@ func containsHelper(s, substr string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func BenchmarkValidateArgs(b *testing.B) {
|
||||
v := NewScriptValidator()
|
||||
args := []string{"--input", "file.txt", "--name", "report 2024", "--out", "/tmp/x", "--verbose", "--limit=50"}
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = v.ValidateArgs(args)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user