Browse code

Revert environment regexp from 13694

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/09/29 03:26:20
Showing 4 changed files
... ...
@@ -4,18 +4,22 @@ import (
4 4
 	"bufio"
5 5
 	"fmt"
6 6
 	"os"
7
-	"regexp"
8 7
 	"strings"
9 8
 )
10 9
 
11
-var (
12
-	// EnvironmentVariableRegexp is a regexp to validate correct environment variables
13
-	// Environment variables set by the user must have a name consisting solely of
14
-	// alphabetics, numerics, and underscores - the first of which must not be numeric.
15
-	EnvironmentVariableRegexp = regexp.MustCompile("^[[:alpha:]_][[:alpha:][:digit:]_]*$")
16
-)
17
-
18 10
 // ParseEnvFile reads a file with environment variables enumerated by lines
11
+//
12
+// ``Environment variable names used by the utilities in the Shell and
13
+// Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase
14
+// letters, digits, and the '_' (underscore) from the characters defined in
15
+// Portable Character Set and do not begin with a digit. *But*, other
16
+// characters may be permitted by an implementation; applications shall
17
+// tolerate the presence of such names.''
18
+// -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
19
+//
20
+// As of #16585, it's up to application inside docker to validate or not
21
+// environment variables, that's why we just strip leading whitespace and
22
+// nothing more.
19 23
 func ParseEnvFile(filename string) ([]string, error) {
20 24
 	fh, err := os.Open(filename)
21 25
 	if err != nil {
... ...
@@ -31,11 +35,13 @@ func ParseEnvFile(filename string) ([]string, error) {
31 31
 		// line is not empty, and not starting with '#'
32 32
 		if len(line) > 0 && !strings.HasPrefix(line, "#") {
33 33
 			data := strings.SplitN(line, "=", 2)
34
-			variable := data[0]
35 34
 
36
-			if !EnvironmentVariableRegexp.MatchString(variable) {
37
-				return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' is not a valid environment variable", variable)}
35
+			// trim the front of a variable, but nothing else
36
+			variable := strings.TrimLeft(data[0], whiteSpaces)
37
+			if strings.ContainsAny(variable, whiteSpaces) {
38
+				return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)}
38 39
 			}
40
+
39 41
 			if len(data) > 1 {
40 42
 
41 43
 				// pass the value through, no trimming
... ...
@@ -28,6 +28,8 @@ func TestParseEnvFileGoodFile(t *testing.T) {
28 28
 # comment
29 29
 
30 30
 _foobar=foobaz
31
+with.dots=working
32
+and_underscore=working too
31 33
 `
32 34
 	// Adding a newline + a line with pure whitespace.
33 35
 	// This is being done like this instead of the block above
... ...
@@ -47,6 +49,8 @@ _foobar=foobaz
47 47
 		"foo=bar",
48 48
 		"baz=quux",
49 49
 		"_foobar=foobaz",
50
+		"with.dots=working",
51
+		"and_underscore=working too",
50 52
 	}
51 53
 
52 54
 	if !reflect.DeepEqual(lines, expectedLines) {
... ...
@@ -96,7 +100,7 @@ func TestParseEnvFileBadlyFormattedFile(t *testing.T) {
96 96
 	if _, ok := err.(ErrBadEnvVariable); !ok {
97 97
 		t.Fatalf("Expected a ErrBadEnvVariable, got [%v]", err)
98 98
 	}
99
-	expectedMessage := "poorly formatted environment: variable 'f   ' is not a valid environment variable"
99
+	expectedMessage := "poorly formatted environment: variable 'f   ' has white spaces"
100 100
 	if err.Error() != expectedMessage {
101 101
 		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
102 102
 	}
... ...
@@ -131,7 +135,7 @@ another invalid line`
131 131
 	if _, ok := err.(ErrBadEnvVariable); !ok {
132 132
 		t.Fatalf("Expected a ErrBadEnvvariable, got [%v]", err)
133 133
 	}
134
-	expectedMessage := "poorly formatted environment: variable 'first line' is not a valid environment variable"
134
+	expectedMessage := "poorly formatted environment: variable 'first line' has white spaces"
135 135
 	if err.Error() != expectedMessage {
136 136
 		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
137 137
 	}
... ...
@@ -256,16 +256,16 @@ func validatePath(val string, validator func(string) bool) (string, error) {
256 256
 }
257 257
 
258 258
 // ValidateEnv validates an environment variable and returns it.
259
-// It uses EnvironmentVariableRegexp to ensure the name of the environment variable is valid.
260 259
 // If no value is specified, it returns the current value using os.Getenv.
260
+//
261
+// As on ParseEnvFile and related to #16585, environment variable names
262
+// are not validate what so ever, it's up to application inside docker
263
+// to validate them or not.
261 264
 func ValidateEnv(val string) (string, error) {
262 265
 	arr := strings.Split(val, "=")
263 266
 	if len(arr) > 1 {
264 267
 		return val, nil
265 268
 	}
266
-	if !EnvironmentVariableRegexp.MatchString(arr[0]) {
267
-		return val, ErrBadEnvVariable{fmt.Sprintf("variable '%s' is not a valid environment variable", val)}
268
-	}
269 269
 	if !doesEnvExist(val) {
270 270
 		return val, nil
271 271
 	}
... ...
@@ -377,35 +377,23 @@ func TestValidateDevice(t *testing.T) {
377 377
 }
378 378
 
379 379
 func TestValidateEnv(t *testing.T) {
380
-	invalids := map[string]string{
381
-		"some spaces": "poorly formatted environment: variable 'some spaces' is not a valid environment variable",
382
-		"asd!qwe":     "poorly formatted environment: variable 'asd!qwe' is not a valid environment variable",
383
-		"1asd":        "poorly formatted environment: variable '1asd' is not a valid environment variable",
384
-		"123":         "poorly formatted environment: variable '123' is not a valid environment variable",
385
-	}
386 380
 	valids := map[string]string{
387
-		"a":                  "a",
388
-		"something":          "something",
389
-		"_=a":                "_=a",
390
-		"env1=value1":        "env1=value1",
391
-		"_env1=value1":       "_env1=value1",
392
-		"env2=value2=value3": "env2=value2=value3",
393
-		"env3=abc!qwe":       "env3=abc!qwe",
394
-		"env_4=value 4":      "env_4=value 4",
395
-		"PATH":               fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
396
-		"PATH=something":     "PATH=something",
397
-	}
398
-	for value, expectedError := range invalids {
399
-		_, err := ValidateEnv(value)
400
-		if err == nil {
401
-			t.Fatalf("Expected ErrBadEnvVariable, got nothing")
402
-		}
403
-		if _, ok := err.(ErrBadEnvVariable); !ok {
404
-			t.Fatalf("Expected ErrBadEnvVariable, got [%s]", err)
405
-		}
406
-		if err.Error() != expectedError {
407
-			t.Fatalf("Expected ErrBadEnvVariable with message [%s], got [%s]", expectedError, err.Error())
408
-		}
381
+		"a":                   "a",
382
+		"something":           "something",
383
+		"_=a":                 "_=a",
384
+		"env1=value1":         "env1=value1",
385
+		"_env1=value1":        "_env1=value1",
386
+		"env2=value2=value3":  "env2=value2=value3",
387
+		"env3=abc!qwe":        "env3=abc!qwe",
388
+		"env_4=value 4":       "env_4=value 4",
389
+		"PATH":                fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
390
+		"PATH=something":      "PATH=something",
391
+		"asd!qwe":             "asd!qwe",
392
+		"1asd":                "1asd",
393
+		"123":                 "123",
394
+		"some space":          "some space",
395
+		"  some space before": "  some space before",
396
+		"some space after  ":  "some space after  ",
409 397
 	}
410 398
 	for value, expected := range valids {
411 399
 		actual, err := ValidateEnv(value)