Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 18:30 UTC
caddyfile: fix nested quotes formatted incorrectly by fmt (#7045)
* Fix incorrectly formatted quote within quotes with fmt * Fix incorrectly formatted quote within quotes with fmt
Ted committed
Oct 28, 2025 at 01:13 UTC
92c8bc73228aad9eb0b396fdb687c024124d8dbd
2 files changed
+38
-16
caddyconfig/caddyfile/formatter.go
+33
-16
@@ -52,17 +52,16 @@ func Format(input []byte) []byte {
52
53
newLines int // count of newlines consumed
54
55
- comment bool // whether we're in a comment
56
- quoted bool // whether we're in a quoted segment
57
- escaped bool // whether current char is escaped
55
+ comment bool // whether we're in a comment
56
+ quotes string // encountered quotes ('', '`', '"', '"`', '`"')
57
+ escaped bool // whether current char is escaped
58
59
heredoc heredocState // whether we're in a heredoc
60
heredocEscaped bool // whether heredoc is escaped
61
heredocMarker []rune
62
heredocClosingMarker []rune
63
64
- nesting int // indentation level
65
- withinBackquote bool
64
+ nesting int // indentation level
65
)
66
67
write := func(ch rune) {
@@ -89,12 +88,8 @@ func Format(input []byte) []byte {
88
}
89
panic(err)
90
}
92
- if ch == '`' {
93
- withinBackquote = !withinBackquote
94
- }
95
-
91
// detect whether we have the start of a heredoc
97
- if !quoted && (heredoc == heredocClosed && !heredocEscaped) &&
92
+ if quotes == "" && (heredoc == heredocClosed && !heredocEscaped) &&
93
space && last == '<' && ch == '<' {
94
write(ch)
95
heredoc = heredocOpening
@@ -180,16 +175,38 @@ func Format(input []byte) []byte {
175
continue
176
}
177
183
- if quoted {
178
+ if ch == '`' {
179
+ switch quotes {
180
+ case "\"`":
181
+ quotes = "\""
182
+ case "`":
183
+ quotes = ""
184
+ case "\"":
185
+ quotes = "\"`"
186
+ default:
187
+ quotes = "`"
188
+ }
189
+ }
190
+
191
+ if quotes == "\"" {
192
if ch == '"' {
185
- quoted = false
193
+ quotes = ""
194
}
195
write(ch)
196
continue
197
}
198
191
- if space && ch == '"' {
192
- quoted = true
199
+ if ch == '"' {
200
+ switch quotes {
201
+ case "":
202
+ if space {
203
+ quotes = "\""
204
+ }
205
+ case "`\"":
206
+ quotes = "`"
207
+ case "\"`":
208
+ quotes = ""
209
+ }
210
}
211
212
if unicode.IsSpace(ch) {
@@ -245,7 +262,7 @@ func Format(input []byte) []byte {
262
write(' ')
263
}
264
openBraceWritten = false
248
- if withinBackquote {
265
+ if quotes == "`" {
266
write('{')
267
openBraceWritten = true
268
continue
@@ -253,7 +270,7 @@ func Format(input []byte) []byte {
270
continue
271
272
case ch == '}' && (spacePrior || !openBrace):
256
- if withinBackquote {
273
+ if quotes == "`" {
274
write('}')
275
continue
276
}
caddyconfig/caddyfile/formatter_test.go
+5
@@ -444,6 +444,11 @@ block2 {
444
input: "block {respond \"All braces should remain: {{now | date `2006`}}\"}",
445
expect: "block {respond \"All braces should remain: {{now | date `2006`}}\"}",
446
},
447
+ {
448
+ description: "Preserve quoted backticks and backticked quotes",
449
+ input: "block { respond \"`\" } block { respond `\"`}",
450
+ expect: "block {\n\trespond \"`\"\n}\n\nblock {\n\trespond `\"`\n}",
451
+ },
452
{
453
description: "No trailing space on line before env variable",
454
input: `{