From 52305618dfc4289e5a3cfcf848450500ef8fa21c Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Tue, 5 May 2020 12:27:49 -0600 Subject: [PATCH] caddyfile: Support backticks as quotes (closes #2591) (#3242) --- caddyconfig/caddyfile/lexer.go | 17 ++++++++++----- caddyconfig/caddyfile/lexer_test.go | 32 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/caddyconfig/caddyfile/lexer.go b/caddyconfig/caddyfile/lexer.go index 687ff90e3..d9968ff8d 100755 --- a/caddyconfig/caddyfile/lexer.go +++ b/caddyconfig/caddyfile/lexer.go @@ -73,7 +73,7 @@ func (l *lexer) load(input io.Reader) error { // a token was loaded; false otherwise. func (l *lexer) next() bool { var val []rune - var comment, quoted, escaped bool + var comment, quoted, btQuoted, escaped bool makeToken := func() bool { l.token.Text = string(val) @@ -92,13 +92,13 @@ func (l *lexer) next() bool { panic(err) } - if !escaped && ch == '\\' { + if !escaped && !btQuoted && ch == '\\' { escaped = true continue } - if quoted { - if escaped { + if quoted || btQuoted { + if quoted && escaped { // all is literal in quoted area, // so only escape quotes if ch != '"' { @@ -106,7 +106,10 @@ func (l *lexer) next() bool { } escaped = false } else { - if ch == '"' { + if quoted && ch == '"' { + return makeToken() + } + if btQuoted && ch == '`' { return makeToken() } } @@ -151,6 +154,10 @@ func (l *lexer) next() bool { quoted = true continue } + if ch == '`' { + btQuoted = true + continue + } } if escaped { diff --git a/caddyconfig/caddyfile/lexer_test.go b/caddyconfig/caddyfile/lexer_test.go index 9105eb570..734006e3b 100755 --- a/caddyconfig/caddyfile/lexer_test.go +++ b/caddyconfig/caddyfile/lexer_test.go @@ -199,6 +199,38 @@ func TestLexer(t *testing.T) { {Line: 1, Text: ":8080"}, }, }, + { + input: "simple `backtick quoted` string", + expected: []Token{ + {Line: 1, Text: `simple`}, + {Line: 1, Text: `backtick quoted`}, + {Line: 1, Text: `string`}, + }, + }, + { + input: "multiline `backtick\nquoted\n` string", + expected: []Token{ + {Line: 1, Text: `multiline`}, + {Line: 1, Text: "backtick\nquoted\n"}, + {Line: 3, Text: `string`}, + }, + }, + { + input: "nested `\"quotes inside\" backticks` string", + expected: []Token{ + {Line: 1, Text: `nested`}, + {Line: 1, Text: `"quotes inside" backticks`}, + {Line: 1, Text: `string`}, + }, + }, + { + input: "reverse-nested \"`backticks` inside\" quotes", + expected: []Token{ + {Line: 1, Text: `reverse-nested`}, + {Line: 1, Text: "`backticks` inside"}, + {Line: 1, Text: `quotes`}, + }, + }, } for i, testCase := range testCases {