From 2b500e63cbc8e91235deafa09bb0d8fe34d443e2 Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Sat, 3 Sep 2016 15:06:42 -0700 Subject: [PATCH] Return error if env file contains non-ascii or utf8 bytes (for windows) This fix tries to address the issue raised in 26179 where an env file with non-ascii or utf8 bytes will crash on windows platform. The issue is two-fold: - Windows will adds a BOM mark at the begining with Notepad as the editor - Non-utf8 bytes can not be handled by env file parser. This fix removes utf8 BOM marker if exists so that utf8 encoded env file could be processed. This fix also returns an error (instead of a runtime CreateProcess crash) if env file contains non-utf8 bytes, thus giving users better experiences. Additional test cases has been added in unit tests. This fix fixes 26179. Signed-off-by: Yong Tang Upstream-commit: 01d3a16f58118a3f6a6207fcb028bb279eb16e73 Component: engine --- components/engine/runconfig/opts/envfile.go | 16 ++++++++++- .../engine/runconfig/opts/fixtures/utf16.env | Bin 0 -> 54 bytes .../runconfig/opts/fixtures/utf16be.env | Bin 0 -> 54 bytes .../engine/runconfig/opts/fixtures/utf8.env | 3 ++ .../engine/runconfig/opts/parse_test.go | 27 ++++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100755 components/engine/runconfig/opts/fixtures/utf16.env create mode 100755 components/engine/runconfig/opts/fixtures/utf16be.env create mode 100755 components/engine/runconfig/opts/fixtures/utf8.env diff --git a/components/engine/runconfig/opts/envfile.go b/components/engine/runconfig/opts/envfile.go index ba8b4f2016..f723799215 100644 --- a/components/engine/runconfig/opts/envfile.go +++ b/components/engine/runconfig/opts/envfile.go @@ -2,9 +2,12 @@ package opts import ( "bufio" + "bytes" "fmt" "os" "strings" + "unicode" + "unicode/utf8" ) // ParseEnvFile reads a file with environment variables enumerated by lines @@ -29,9 +32,20 @@ func ParseEnvFile(filename string) ([]string, error) { lines := []string{} scanner := bufio.NewScanner(fh) + currentLine := 0 + utf8bom := []byte{0xEF, 0xBB, 0xBF} for scanner.Scan() { + scannedBytes := scanner.Bytes() + if !utf8.Valid(scannedBytes) { + return []string{}, fmt.Errorf("env file %s contains invalid utf8 bytes at line %d: %v", filename, currentLine+1, scannedBytes) + } + // We trim UTF8 BOM + if currentLine == 0 { + scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom) + } // trim the line from all leading whitespace first - line := strings.TrimLeft(scanner.Text(), whiteSpaces) + line := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace) + currentLine++ // line is not empty, and not starting with '#' if len(line) > 0 && !strings.HasPrefix(line, "#") { data := strings.SplitN(line, "=", 2) diff --git a/components/engine/runconfig/opts/fixtures/utf16.env b/components/engine/runconfig/opts/fixtures/utf16.env new file mode 100755 index 0000000000000000000000000000000000000000..3a73358fffbc0d5d3d4df985ccf2f4a1a29cdb2a GIT binary patch literal 54 ucmezW&yB$!2yGdh7#tab7