From 80febc7c07fd6f8ab8d93255a99572e0e39a99ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Tue, 3 Jan 2023 18:43:00 +0100 Subject: [PATCH] add support for multi-line values with \ This is explicitely valid as per https://git-scm.com/docs/git-config#_syntax > A line that defines a value can be continued to the next line by ending it with a \; --- read.go | 2 +- read_test.go | 6 ++++++ scanner/scanner.go | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/read.go b/read.go index 4dfdc5c..7a139f4 100644 --- a/read.go +++ b/read.go @@ -12,7 +12,7 @@ import ( "gopkg.in/warnings.v0" ) -var unescape = map[rune]rune{'\\': '\\', '"': '"', 'n': '\n', 't': '\t', 'b': '\b'} +var unescape = map[rune]rune{'\\': '\\', '"': '"', 'n': '\n', 't': '\t', 'b': '\b', '\n': '\n'} // no error: invalid literals should be caught by scanner func unquote(s string) string { diff --git a/read_test.go b/read_test.go index e2727f1..684322a 100644 --- a/read_test.go +++ b/read_test.go @@ -399,6 +399,10 @@ func TestReadWithCallback(t *testing.T) { key5= [sect1 "subsect2"] [sect2] + [sect3] + foo = "!f(){ \ + echo hello; \ + };f" ` expected := [][]string{ []string{"sect1", "", "", "", "true"}, @@ -410,6 +414,8 @@ func TestReadWithCallback(t *testing.T) { []string{"sect1", "subsect1", "key5", "", "false"}, []string{"sect1", "subsect2", "", "", "true"}, []string{"sect2", "", "", "", "true"}, + []string{"sect3", "", "", "", "true"}, + []string{"sect3", "", "foo", "!f(){ \n\techo hello; \n\t};f", "false"}, } err := ReadWithCallback(bytes.NewReader([]byte(text)), cb) if err != nil { diff --git a/scanner/scanner.go b/scanner/scanner.go index 41aafec..63cff72 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -163,12 +163,13 @@ func (s *Scanner) scanIdentifier() string { return string(s.src[offs:s.offset]) } +// val indicate if we are scanning a value (vs a header) func (s *Scanner) scanEscape(val bool) { offs := s.offset ch := s.ch s.next() // always make progress switch ch { - case '\\', '"': + case '\\', '"', '\n': // ok case 'n', 't', 'b': if val {