Limit unclosed placeholder tolerance (fix #4170)

This commit is contained in:
Matthew Holt 2022-09-15 13:36:08 -06:00
parent e338648fed
commit 2dc747cf2d
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
1 changed files with 12 additions and 1 deletions

View File

@ -144,9 +144,11 @@ func (r *Replacer) replace(input, empty string,
// iterate the input to find each placeholder
var lastWriteCursor int
// fail fast if too many placeholders are unclosed
var unclosedCount int
scan:
for i := 0; i < len(input); i++ {
// check for escaped braces
if i > 0 && input[i-1] == phEscape && (input[i] == phClose || input[i] == phOpen) {
sb.WriteString(input[lastWriteCursor : i-1])
@ -158,9 +160,17 @@ scan:
continue
}
// our iterator is now on an unescaped open brace (start of placeholder)
// too many unclosed placeholders in absolutely ridiculous input can be extremely slow (issue #4170)
if unclosedCount > 100 {
return "", fmt.Errorf("too many unclosed placeholders")
}
// find the end of the placeholder
end := strings.Index(input[i:], string(phClose)) + i
if end < i {
unclosedCount++
continue
}
@ -168,6 +178,7 @@ scan:
for end > 0 && end < len(input)-1 && input[end-1] == phEscape {
nextEnd := strings.Index(input[end+1:], string(phClose))
if nextEnd < 0 {
unclosedCount++
continue scan
}
end += nextEnd + 1