From 2501691ea4ce7f5d729513250480bac84d1830ae Mon Sep 17 00:00:00 2001
From: Matthew Holt <Matthew.Holt+git@gmail.com>
Date: Fri, 8 May 2015 10:32:57 -0600
Subject: [PATCH] lexer: Fixed backslashes in quoted strings (closes #65)

---
 config/parse/lexer.go      | 14 +++++++++++---
 config/parse/lexer_test.go | 26 ++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/config/parse/lexer.go b/config/parse/lexer.go
index 5e0e46d54..32efc9e20 100644
--- a/config/parse/lexer.go
+++ b/config/parse/lexer.go
@@ -36,9 +36,11 @@ func (l *lexer) load(input io.Reader) error {
 // the token starts with a quotes character (")
 // in which case the token goes until the closing
 // quotes (the enclosing quotes are not included).
-// The rest of the line is skipped if a "#"
-// character is read in. Returns true if a token
-// was loaded; false otherwise.
+// Inside quoted strings, quotes may be escaped
+// with a preceding \ character. No other chars
+// may be escaped. The rest of the line is skipped
+// if a "#" character is read in. Returns true if
+// a token was loaded; false otherwise.
 func (l *lexer) next() bool {
 	var val []rune
 	var comment, quoted, escaped bool
@@ -74,6 +76,12 @@ func (l *lexer) next() bool {
 			if ch == '\n' {
 				l.line++
 			}
+			if escaped {
+				// only escape quotes
+				if ch != '"' {
+					val = append(val, '\\')
+				}
+			}
 			val = append(val, ch)
 			escaped = false
 			continue
diff --git a/config/parse/lexer_test.go b/config/parse/lexer_test.go
index 99f8501e8..f12c7e7dc 100644
--- a/config/parse/lexer_test.go
+++ b/config/parse/lexer_test.go
@@ -80,6 +80,18 @@ func TestLexer(t *testing.T) {
 				{line: 1, text: "B"},
 			},
 		},
+		{
+			input: `"don't\escape"`,
+			expected: []token{
+				{line: 1, text: `don't\escape`},
+			},
+		},
+		{
+			input: `"don't\\escape"`,
+			expected: []token{
+				{line: 1, text: `don't\\escape`},
+			},
+		},
 		{
 			input: `A "quoted value with line
 					break inside" {
@@ -93,6 +105,20 @@ func TestLexer(t *testing.T) {
 				{line: 4, text: "}"},
 			},
 		},
+		{
+			input: `"C:\php\php-cgi.exe"`,
+			expected: []token{
+				{line: 1, text: `C:\php\php-cgi.exe`},
+			},
+		},
+		{
+			input: `empty "" string`,
+			expected: []token{
+				{line: 1, text: `empty`},
+				{line: 1, text: ``},
+				{line: 1, text: `string`},
+			},
+		},
 		{
 			input: "skip those\r\nCR characters",
 			expected: []token{