waveterm/pkg/util/envutil/envutil.go
2024-11-19 17:20:47 -08:00

70 lines
1.5 KiB
Go

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package envutil
import (
"fmt"
"strings"
)
const MaxEnvSize = 1024 * 1024
// env format:
// KEY=VALUE\0
// keys cannot have '=' or '\0' in them
// values can have '=' but not '\0'
func EnvToMap(envStr string) map[string]string {
rtn := make(map[string]string)
envLines := strings.Split(envStr, "\x00")
for _, line := range envLines {
if len(line) == 0 {
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) == 2 {
rtn[parts[0]] = parts[1]
}
}
return rtn
}
func MapToEnv(envMap map[string]string) string {
var sb strings.Builder
for key, val := range envMap {
sb.WriteString(key)
sb.WriteByte('=')
sb.WriteString(val)
sb.WriteByte('\x00')
}
return sb.String()
}
func GetEnv(envStr string, key string) string {
envMap := EnvToMap(envStr)
return envMap[key]
}
func SetEnv(envStr string, key string, val string) (string, error) {
if strings.ContainsAny(key, "=\x00") {
return "", fmt.Errorf("key cannot contain '=' or '\\x00'")
}
if strings.Contains(val, "\x00") {
return "", fmt.Errorf("value cannot contain '\\x00'")
}
if len(key)+len(val)+2+len(envStr) > MaxEnvSize {
return "", fmt.Errorf("env string too large (max %d bytes)", MaxEnvSize)
}
envMap := EnvToMap(envStr)
envMap[key] = val
rtnStr := MapToEnv(envMap)
return rtnStr, nil
}
func RmEnv(envStr string, key string) string {
envMap := EnvToMap(envStr)
delete(envMap, key)
return MapToEnv(envMap)
}