4
4
package envutil
5
5
6
6
import (
7
+ "fmt"
7
8
"os"
9
+ "regexp"
8
10
"slices"
9
11
"strings"
10
12
@@ -42,27 +44,55 @@ var defaultBlockList = []string{
42
44
"_*" , // Variables starting with underscore are typically internal
43
45
}
44
46
47
+ func validatePattern (pattern string ) error {
48
+ invalidChar := regexp .MustCompile (`([^a-zA-Z0-9_*])` )
49
+ if matches := invalidChar .FindStringSubmatch (pattern ); matches != nil {
50
+ invalidCharacter := matches [1 ]
51
+ pos := strings .Index (pattern , invalidCharacter )
52
+ return fmt .Errorf ("pattern %q contains invalid character %q at position %d" ,
53
+ pattern , invalidCharacter , pos )
54
+ }
55
+ return nil
56
+ }
57
+
45
58
// getBlockList returns the list of environment variable patterns to be blocked.
46
- // The second return value indicates whether the list was explicitly set via LIMA_SHELLENV_BLOCK.
47
- func getBlockList () ([]string , bool ) {
59
+ func getBlockList () []string {
48
60
blockEnv := os .Getenv ("LIMA_SHELLENV_BLOCK" )
49
61
if blockEnv == "" {
50
- return defaultBlockList , false
62
+ return defaultBlockList
51
63
}
52
- after , found := strings .CutPrefix (blockEnv , "+" )
53
- if ! found {
54
- return parseEnvList (blockEnv ), true
64
+
65
+ shouldAppend := strings .HasPrefix (blockEnv , "+" )
66
+ patterns := parseEnvList (strings .TrimPrefix (blockEnv , "+" ))
67
+
68
+ for _ , pattern := range patterns {
69
+ if err := validatePattern (pattern ); err != nil {
70
+ logrus .Fatalf ("Invalid LIMA_SHELLENV_BLOCK pattern: %v" , err )
71
+ }
72
+ }
73
+
74
+ if shouldAppend {
75
+ return slices .Concat (defaultBlockList , patterns )
55
76
}
56
- return slices . Concat ( defaultBlockList , parseEnvList ( after )), true
77
+ return patterns
57
78
}
58
79
59
80
// getAllowList returns the list of environment variable patterns to be allowed.
60
- // The second return value indicates whether the list was explicitly set via LIMA_SHELLENV_ALLOW.
61
- func getAllowList () ([] string , bool ) {
62
- if allowEnv := os . Getenv ( "LIMA_SHELLENV_ALLOW" ); allowEnv ! = "" {
63
- return parseEnvList ( allowEnv ), true
81
+ func getAllowList () [] string {
82
+ allowEnv := os . Getenv ( "LIMA_SHELLENV_ALLOW" )
83
+ if allowEnv = = "" {
84
+ return nil
64
85
}
65
- return nil , false
86
+
87
+ patterns := parseEnvList (allowEnv )
88
+
89
+ for _ , pattern := range patterns {
90
+ if err := validatePattern (pattern ); err != nil {
91
+ logrus .Fatalf ("Invalid LIMA_SHELLENV_ALLOW pattern: %v" , err )
92
+ }
93
+ }
94
+
95
+ return patterns
66
96
}
67
97
68
98
func parseEnvList (envList string ) []string {
@@ -82,8 +112,14 @@ func matchesPattern(name, pattern string) bool {
82
112
return true
83
113
}
84
114
85
- prefix , found := strings .CutSuffix (pattern , "*" )
86
- return found && strings .HasPrefix (name , prefix )
115
+ regexPattern := strings .ReplaceAll (pattern , "*" , ".*" )
116
+ regexPattern = "^" + regexPattern + "$"
117
+
118
+ match , err := regexp .MatchString (regexPattern , name )
119
+ if err != nil {
120
+ return false
121
+ }
122
+ return match
87
123
}
88
124
89
125
func matchesAnyPattern (name string , patterns []string ) bool {
@@ -96,17 +132,10 @@ func matchesAnyPattern(name string, patterns []string) bool {
96
132
// It returns a slice of environment variables that are not blocked by the current configuration.
97
133
// The filtering is controlled by LIMA_SHELLENV_BLOCK and LIMA_SHELLENV_ALLOW environment variables.
98
134
func FilterEnvironment () []string {
99
- allowList , isAllowListSet := getAllowList ()
100
- blockList , isBlockListSet := getBlockList ()
101
-
102
- if isBlockListSet && isAllowListSet {
103
- logrus .Warn ("Both LIMA_SHELLENV_BLOCK and LIMA_SHELLENV_ALLOW are set. Block list will be ignored." )
104
- blockList = nil
105
- }
106
135
return filterEnvironmentWithLists (
107
136
os .Environ (),
108
- allowList ,
109
- blockList ,
137
+ getAllowList () ,
138
+ getBlockList () ,
110
139
)
111
140
}
112
141
@@ -121,10 +150,7 @@ func filterEnvironmentWithLists(env, allowList, blockList []string) []string {
121
150
122
151
name := parts [0 ]
123
152
124
- if len (allowList ) > 0 {
125
- if ! matchesAnyPattern (name , allowList ) {
126
- continue
127
- }
153
+ if len (allowList ) > 0 && matchesAnyPattern (name , allowList ) {
128
154
filtered = append (filtered , envVar )
129
155
continue
130
156
}
0 commit comments