58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package aviation
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"regexp"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
// DefaultRegexTimeout is the maximum time allowed for regex matching operations.
|
||
|
|
// This prevents ReDoS (Regular Expression Denial of Service) attacks from
|
||
|
|
// maliciously crafted inputs that cause catastrophic backtracking.
|
||
|
|
DefaultRegexTimeout = 100 * time.Millisecond
|
||
|
|
)
|
||
|
|
|
||
|
|
// MatchWithTimeout executes a regex match with timeout protection.
|
||
|
|
// It runs the regex matching in a goroutine and returns an error if the
|
||
|
|
// operation exceeds the specified timeout duration.
|
||
|
|
//
|
||
|
|
// This is critical for preventing ReDoS attacks where complex patterns
|
||
|
|
// (especially the FPL pattern with nested quantifiers) could hang indefinitely
|
||
|
|
// on malicious input.
|
||
|
|
//
|
||
|
|
// Parameters:
|
||
|
|
// - re: The compiled regular expression to match
|
||
|
|
// - input: The input string to match against
|
||
|
|
// - timeout: Maximum duration allowed for the match operation
|
||
|
|
//
|
||
|
|
// Returns:
|
||
|
|
// - []string: The match result (same format as regexp.FindStringSubmatch)
|
||
|
|
// - error: ValidationError if timeout occurs, nil otherwise
|
||
|
|
func MatchWithTimeout(re *regexp.Regexp, input string, timeout time.Duration) ([]string, error) {
|
||
|
|
type result struct {
|
||
|
|
match []string
|
||
|
|
}
|
||
|
|
|
||
|
|
resultChan := make(chan result, 1)
|
||
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||
|
|
defer cancel()
|
||
|
|
|
||
|
|
// Run regex matching in a goroutine
|
||
|
|
go func() {
|
||
|
|
match := re.FindStringSubmatch(input)
|
||
|
|
resultChan <- result{match: match}
|
||
|
|
}()
|
||
|
|
|
||
|
|
// Wait for either result or timeout
|
||
|
|
select {
|
||
|
|
case res := <-resultChan:
|
||
|
|
return res.match, nil
|
||
|
|
case <-ctx.Done():
|
||
|
|
return nil, &ValidationError{
|
||
|
|
Field: "regex_timeout",
|
||
|
|
Message: "regex matching exceeded timeout",
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|