forked from coop-cloud-mirrors/godotenv
Merge pull request #34 from alexquick/fix-parsing-issues
Fix some small parsing bugs
This commit is contained in:
commit
c9360df4d1
41
godotenv.go
41
godotenv.go
@ -19,6 +19,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -203,11 +204,11 @@ func parseLine(line string) (key string, value string, err error) {
|
||||
line = strings.Join(segmentsToKeep, "#")
|
||||
}
|
||||
|
||||
// now split key from value
|
||||
firstEquals := strings.Index(line, "=")
|
||||
firstColon := strings.Index(line, ":")
|
||||
splitString := strings.SplitN(line, "=", 2)
|
||||
|
||||
if len(splitString) != 2 {
|
||||
// try yaml mode!
|
||||
if firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) {
|
||||
//this is a yaml-style line
|
||||
splitString = strings.SplitN(line, ":", 2)
|
||||
}
|
||||
|
||||
@ -224,27 +225,39 @@ func parseLine(line string) (key string, value string, err error) {
|
||||
key = strings.Trim(key, " ")
|
||||
|
||||
// Parse the value
|
||||
value = splitString[1]
|
||||
value = parseValue(splitString[1])
|
||||
return
|
||||
}
|
||||
|
||||
func parseValue(value string) string {
|
||||
|
||||
// trim
|
||||
value = strings.Trim(value, " ")
|
||||
|
||||
// check if we've got quoted values
|
||||
if value != "" {
|
||||
// check if we've got quoted values or possible escapes
|
||||
if len(value) > 1 {
|
||||
first := string(value[0:1])
|
||||
last := string(value[len(value)-1:])
|
||||
if first == last && strings.ContainsAny(first, `"'`) {
|
||||
// pull the quotes off the edges
|
||||
value = strings.Trim(value, `"'`)
|
||||
|
||||
// expand quotes
|
||||
value = strings.Replace(value, `\"`, `"`, -1)
|
||||
// expand newlines
|
||||
value = strings.Replace(value, `\n`, "\n", -1)
|
||||
value = value[1 : len(value)-1]
|
||||
// handle escapes
|
||||
escapeRegex := regexp.MustCompile(`\\.`)
|
||||
value = escapeRegex.ReplaceAllStringFunc(value, func(match string) string {
|
||||
c := strings.TrimPrefix(match, `\`)
|
||||
switch c {
|
||||
case "n":
|
||||
return "\n"
|
||||
case "r":
|
||||
return "\r"
|
||||
default:
|
||||
return c
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return value
|
||||
}
|
||||
|
||||
func isIgnoredLine(line string) bool {
|
||||
|
@ -217,9 +217,18 @@ func TestParsing(t *testing.T) {
|
||||
// parses escaped double quotes
|
||||
parseAndCompare(t, `FOO="escaped\"bar"`, "FOO", `escaped"bar`)
|
||||
|
||||
// parses single quotes inside double quotes
|
||||
parseAndCompare(t, `FOO="'d'"`, "FOO", `'d'`)
|
||||
|
||||
// parses yaml style options
|
||||
parseAndCompare(t, "OPTION_A: 1", "OPTION_A", "1")
|
||||
|
||||
//parses yaml values with equal signs
|
||||
parseAndCompare(t, "OPTION_A: Foo=bar", "OPTION_A", "Foo=bar")
|
||||
|
||||
// parses non-yaml options with colons
|
||||
parseAndCompare(t, "OPTION_A=1:B", "OPTION_A", "1:B")
|
||||
|
||||
// parses export keyword
|
||||
parseAndCompare(t, "export OPTION_A=2", "OPTION_A", "2")
|
||||
parseAndCompare(t, `export OPTION_B='\n'`, "OPTION_B", "\n")
|
||||
@ -256,6 +265,15 @@ 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
|
||||
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")
|
||||
parseAndCompare(t, `KEY="`, "KEY", "\"")
|
||||
parseAndCompare(t, `KEY="value`, "KEY", "\"value")
|
||||
|
||||
// it 'throws an error if line format is incorrect' do
|
||||
// expect{env('lol$wut')}.to raise_error(Dotenv::FormatError)
|
||||
badlyFormattedLine := "lol$wut"
|
||||
|
Loading…
x
Reference in New Issue
Block a user