MCPcopy
hub / github.com/caddyserver/caddy / replace

Method replace

replacer.go:175–287  ·  view source on GitHub ↗
(input, empty string,
	treatUnknownAsEmpty, errOnEmpty, errOnUnknown bool,
	f ReplacementFunc,
)

Source from the content-addressed store, hash-verified

173}
174
175func (r *Replacer) replace(input, empty string,
176 treatUnknownAsEmpty, errOnEmpty, errOnUnknown bool,
177 f ReplacementFunc,
178) (string, error) {
179 if !strings.Contains(input, string(phOpen)) && !strings.Contains(input, string(phClose)) {
180 return input, nil
181 }
182
183 var sb strings.Builder
184
185 // it is reasonable to assume that the output
186 // will be approximately as long as the input
187 sb.Grow(len(input))
188
189 // iterate the input to find each placeholder
190 var lastWriteCursor int
191
192 // fail fast if too many placeholders are unclosed
193 var unclosedCount int
194
195scan:
196 for i := 0; i < len(input); i++ {
197 // check for escaped braces
198 if i > 0 && input[i-1] == phEscape && (input[i] == phClose || input[i] == phOpen) {
199 sb.WriteString(input[lastWriteCursor : i-1])
200 lastWriteCursor = i
201 continue
202 }
203
204 if input[i] != phOpen {
205 continue
206 }
207
208 // our iterator is now on an unescaped open brace (start of placeholder)
209
210 // too many unclosed placeholders in absolutely ridiculous input can be extremely slow (issue #4170)
211 if unclosedCount > 100 {
212 return "", fmt.Errorf("too many unclosed placeholders")
213 }
214
215 // find the end of the placeholder
216 end := strings.Index(input[i:], string(phClose)) + i
217 if end < i {
218 unclosedCount++
219 continue
220 }
221
222 // if necessary look for the first closing brace that is not escaped
223 for end > 0 && end < len(input)-1 && input[end-1] == phEscape {
224 nextEnd := strings.Index(input[end+1:], string(phClose))
225 if nextEnd < 0 {
226 unclosedCount++
227 continue scan
228 }
229 end += nextEnd + 1
230 }
231
232 // write the substring from the last cursor to this point

Callers 4

ReplaceOrErrMethod · 0.95
ReplaceKnownMethod · 0.95
ReplaceAllMethod · 0.95
ReplaceFuncMethod · 0.95

Calls 3

GetMethod · 0.95
ToStringFunction · 0.85
StringMethod · 0.45

Tested by

no test coverage detected