Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 13, 13:00 UTC
Limit unclosed placeholder tolerance (fix #4170)
Matthew Holt committed
Sep 15, 2022 at 13:36 UTC
2dc747cf2d7dd4e7337c1d7665042b896f3b4445
1 file changed
+12
-1
replacer.go
+12
-1
@@ -144,9 +144,11 @@ func (r *Replacer) replace(input, empty string,
144
// iterate the input to find each placeholder
145
var lastWriteCursor int
146
147
+ // fail fast if too many placeholders are unclosed
148
+ var unclosedCount int
149
+
150
scan:
151
for i := 0; i < len(input); i++ {
149
-
152
// check for escaped braces
153
if i > 0 && input[i-1] == phEscape && (input[i] == phClose || input[i] == phOpen) {
154
sb.WriteString(input[lastWriteCursor : i-1])
@@ -158,9 +160,17 @@ scan:
160
continue
161
}
162
163
+ // our iterator is now on an unescaped open brace (start of placeholder)
164
+
165
+ // too many unclosed placeholders in absolutely ridiculous input can be extremely slow (issue #4170)
166
+ if unclosedCount > 100 {
167
+ return "", fmt.Errorf("too many unclosed placeholders")
168
+ }
169
+
170
// find the end of the placeholder
171
end := strings.Index(input[i:], string(phClose)) + i
172
if end < i {
173
+ unclosedCount++
174
continue
175
}
176
@@ -168,6 +178,7 @@ scan:
178
for end > 0 && end < len(input)-1 && input[end-1] == phEscape {
179
nextEnd := strings.Index(input[end+1:], string(phClose))
180
if nextEnd < 0 {
181
+ unclosedCount++
182
continue scan
183
}
184
end += nextEnd + 1