Skip to content

Commit 629b623

Browse files
committed
generate: replace duplicate env entries
If a given environment variable has already been set, replace the variable rather than appending it to the environment list. This avoids issues with POSIX (which doesn't define what to do with duplicate values). This required a change in the signature of AddProcessEnv, because doing the check by splitting around "=" is just not safe (and brings up questions about variables without "=" in their names that I'd rather punt on). The check if two variables is the same is if they have the same NAME= prefix. Signed-off-by: Aleksa Sarai <asarai@suse.de>
1 parent 308b6d9 commit 629b623

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

cmd/oci-runtime-tool/generate.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,11 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
208208
}
209209

210210
for _, env := range envs {
211-
g.AddProcessEnv(env)
211+
name, value, err := parseEnv(env)
212+
if err != nil {
213+
return err
214+
}
215+
g.AddProcessEnv(name, value)
212216
}
213217
}
214218

@@ -740,6 +744,22 @@ func readKVStrings(files []string, override []string) ([]string, error) {
740744
return envVariables, nil
741745
}
742746

747+
// parseEnv splits a given environment variable (of the form name=value) into
748+
// (name, value). An error is returned if there is no "=" in the line or if the
749+
// name is empty.
750+
func parseEnv(env string) (string, string, error) {
751+
parts := strings.SplitN(env, "=", 2)
752+
if len(parts) != 2 {
753+
return "", "", fmt.Errorf("environment variable must contain '=': %s", env)
754+
}
755+
756+
name, value := parts[0], parts[1]
757+
if name == "" {
758+
return "", "", fmt.Errorf("environment variable must have non-empty name: %s", env)
759+
}
760+
return name, value, nil
761+
}
762+
743763
// parseEnvFile reads a file with environment variables enumerated by lines
744764
//
745765
// ``Environment variable names used by the utilities in the Shell and

generate/generate.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,18 @@ func (g *Generator) ClearProcessEnv() {
331331
g.spec.Process.Env = []string{}
332332
}
333333

334-
// AddProcessEnv adds env into g.spec.Process.Env.
335-
func (g *Generator) AddProcessEnv(env string) {
334+
// AddProcessEnv adds name=value into g.spec.Process.Env, or replaces an
335+
// existing entry with the given name.
336+
func (g *Generator) AddProcessEnv(name, value string) {
336337
g.initSpec()
338+
339+
env := fmt.Sprintf("%s=%s", name, value)
340+
for idx := range g.spec.Process.Env {
341+
if strings.HasPrefix(g.spec.Process.Env[idx], name+"=") {
342+
g.spec.Process.Env[idx] = env
343+
return
344+
}
345+
}
337346
g.spec.Process.Env = append(g.spec.Process.Env, env)
338347
}
339348

0 commit comments

Comments
 (0)