Skip to content
This repository was archived by the owner on Jan 12, 2022. It is now read-only.

Commit c9360df

Browse files
authored
Merge pull request joho#34 from alexquick/fix-parsing-issues
Fix some small parsing bugs
2 parents 59f2022 + a905e99 commit c9360df

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

godotenv.go

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"io"
2020
"os"
2121
"os/exec"
22+
"regexp"
2223
"strings"
2324
)
2425

@@ -203,11 +204,11 @@ func parseLine(line string) (key string, value string, err error) {
203204
line = strings.Join(segmentsToKeep, "#")
204205
}
205206

206-
// now split key from value
207+
firstEquals := strings.Index(line, "=")
208+
firstColon := strings.Index(line, ":")
207209
splitString := strings.SplitN(line, "=", 2)
208-
209-
if len(splitString) != 2 {
210-
// try yaml mode!
210+
if firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) {
211+
//this is a yaml-style line
211212
splitString = strings.SplitN(line, ":", 2)
212213
}
213214

@@ -224,27 +225,39 @@ func parseLine(line string) (key string, value string, err error) {
224225
key = strings.Trim(key, " ")
225226

226227
// Parse the value
227-
value = splitString[1]
228+
value = parseValue(splitString[1])
229+
return
230+
}
231+
232+
func parseValue(value string) string {
228233

229234
// trim
230235
value = strings.Trim(value, " ")
231236

232-
// check if we've got quoted values
233-
if value != "" {
237+
// check if we've got quoted values or possible escapes
238+
if len(value) > 1 {
234239
first := string(value[0:1])
235240
last := string(value[len(value)-1:])
236241
if first == last && strings.ContainsAny(first, `"'`) {
237242
// pull the quotes off the edges
238-
value = strings.Trim(value, `"'`)
239-
240-
// expand quotes
241-
value = strings.Replace(value, `\"`, `"`, -1)
242-
// expand newlines
243-
value = strings.Replace(value, `\n`, "\n", -1)
243+
value = value[1 : len(value)-1]
244+
// handle escapes
245+
escapeRegex := regexp.MustCompile(`\\.`)
246+
value = escapeRegex.ReplaceAllStringFunc(value, func(match string) string {
247+
c := strings.TrimPrefix(match, `\`)
248+
switch c {
249+
case "n":
250+
return "\n"
251+
case "r":
252+
return "\r"
253+
default:
254+
return c
255+
}
256+
})
244257
}
245258
}
246259

247-
return
260+
return value
248261
}
249262

250263
func isIgnoredLine(line string) bool {

godotenv_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,18 @@ func TestParsing(t *testing.T) {
217217
// parses escaped double quotes
218218
parseAndCompare(t, `FOO="escaped\"bar"`, "FOO", `escaped"bar`)
219219

220+
// parses single quotes inside double quotes
221+
parseAndCompare(t, `FOO="'d'"`, "FOO", `'d'`)
222+
220223
// parses yaml style options
221224
parseAndCompare(t, "OPTION_A: 1", "OPTION_A", "1")
222225

226+
//parses yaml values with equal signs
227+
parseAndCompare(t, "OPTION_A: Foo=bar", "OPTION_A", "Foo=bar")
228+
229+
// parses non-yaml options with colons
230+
parseAndCompare(t, "OPTION_A=1:B", "OPTION_A", "1:B")
231+
223232
// parses export keyword
224233
parseAndCompare(t, "export OPTION_A=2", "OPTION_A", "2")
225234
parseAndCompare(t, `export OPTION_B='\n'`, "OPTION_B", "\n")
@@ -256,6 +265,15 @@ func TestParsing(t *testing.T) {
256265
parseAndCompare(t, `FOO="ba#r"`, "FOO", "ba#r")
257266
parseAndCompare(t, "FOO='ba#r'", "FOO", "ba#r")
258267

268+
//newlines and backslashes should be escaped
269+
parseAndCompare(t, `FOO="bar\n\ b\az"`, "FOO", "bar\n baz")
270+
parseAndCompare(t, `FOO="bar\\\n\ b\az"`, "FOO", "bar\\\n baz")
271+
parseAndCompare(t, `FOO="bar\\r\ b\az"`, "FOO", "bar\\r baz")
272+
273+
parseAndCompare(t, `="value"`, "", "value")
274+
parseAndCompare(t, `KEY="`, "KEY", "\"")
275+
parseAndCompare(t, `KEY="value`, "KEY", "\"value")
276+
259277
// it 'throws an error if line format is incorrect' do
260278
// expect{env('lol$wut')}.to raise_error(Dotenv::FormatError)
261279
badlyFormattedLine := "lol$wut"

0 commit comments

Comments
 (0)