From 22b063534c5116bea2f62a650a7b265ecde1ad20 Mon Sep 17 00:00:00 2001 From: budimanjojo Date: Thu, 23 Nov 2023 13:08:06 +0700 Subject: [PATCH] skip YAML document delimiter --- godotenv_test.go | 35 ++++++++++++++++++----------------- parser.go | 2 ++ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/godotenv_test.go b/godotenv_test.go index c6d7e54..b84c574 100644 --- a/godotenv_test.go +++ b/godotenv_test.go @@ -13,7 +13,6 @@ var noopPresets = make(map[string]string) func parseAndCompare(t *testing.T, rawEnvLine string, expectedKey string, expectedValue string) { result, err := Unmarshal(rawEnvLine) - if err != nil { t.Errorf("Expected %q to parse as %q: %q, errored %q", rawEnvLine, expectedKey, expectedValue, err) return @@ -342,7 +341,7 @@ func TestParsing(t *testing.T) { // parses yaml style options parseAndCompare(t, "OPTION_A: 1", "OPTION_A", "1") - //parses yaml values with equal signs + // parses yaml values with equal signs parseAndCompare(t, "OPTION_A: Foo=bar", "OPTION_A", "Foo=bar") // parses non-yaml options with colons @@ -394,13 +393,16 @@ func TestParsing(t *testing.T) { parseAndCompare(t, `FOO="ba#r"`, "FOO", "ba#r") parseAndCompare(t, "FOO='ba#r'", "FOO", "ba#r") - //newlines and backslashes should be escaped + // newlines and backslashes should be escaped parseAndCompare(t, `FOO="bar\n\ b\az"`, "FOO", "bar\n baz") parseAndCompare(t, `FOO="bar\\\n\ b\az"`, "FOO", "bar\\\n baz") parseAndCompare(t, `FOO="bar\\r\ b\az"`, "FOO", "bar\\r baz") parseAndCompare(t, `="value"`, "", "value") + // YAML delimiter should be skipped + parseAndCompare(t, "---\nKEY:value", "KEY", "value") + // unquoted whitespace around keys should be ignored parseAndCompare(t, " KEY =value", "KEY", "value") parseAndCompare(t, " KEY=value", "KEY", "value") @@ -487,14 +489,14 @@ func TestWrite(t *testing.T) { t.Errorf("Expected '%v' (%v) to write as '%v', got '%v' instead.", env, envMap, expected, actual) } } - //just test some single lines to show the general idea - //TestRoundtrip makes most of the good assertions + // just test some single lines to show the general idea + // TestRoundtrip makes most of the good assertions - //values are always double-quoted + // values are always double-quoted writeAndCompare(`key=value`, `key="value"`) - //double-quotes are escaped + // double-quotes are escaped writeAndCompare(`key=va"lu"e`, `key="va\"lu\"e"`) - //but single quotes are left alone + // but single quotes are left alone writeAndCompare(`key=va'lu'e`, `key="va'lu'e"`) // newlines, backslashes, and some other special chars are escaped writeAndCompare(`foo="\n\r\\r!"`, `foo="\n\r\\r\!"`) @@ -502,7 +504,6 @@ func TestWrite(t *testing.T) { writeAndCompare("foo=bar\nbaz=buzz", "baz=\"buzz\"\nfoo=\"bar\"") // integers should not be quoted writeAndCompare(`key="10"`, `key=10`) - } func TestRoundtrip(t *testing.T) { @@ -582,42 +583,42 @@ func TestWhitespace(t *testing.T) { }{ "Leading whitespace": { input: " A=a\n", - key: "A", + key: "A", value: "a", }, "Leading tab": { input: "\tA=a\n", - key: "A", + key: "A", value: "a", }, "Leading mixed whitespace": { input: " \t \t\n\t \t A=a\n", - key: "A", + key: "A", value: "a", }, "Leading whitespace before export": { input: " \t\t export A=a\n", - key: "A", + key: "A", value: "a", }, "Trailing whitespace": { input: "A=a \t \t\n", - key: "A", + key: "A", value: "a", }, "Trailing whitespace with export": { input: "export A=a\t \t \n", - key: "A", + key: "A", value: "a", }, "No EOL": { input: "A=a", - key: "A", + key: "A", value: "a", }, "Trailing whitespace with no EOL": { input: "A=a ", - key: "A", + key: "A", value: "a", }, } diff --git a/parser.go b/parser.go index cc709af..610f58c 100644 --- a/parser.go +++ b/parser.go @@ -18,6 +18,8 @@ const ( ) func parseBytes(src []byte, out map[string]string) error { + // skip YAML document delimiter + src = bytes.Replace(src, []byte("---\n"), []byte("\n"), -1) src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1) cutset := src for {