trpc.group/trpc-go/trpc-go@v1.0.3/internal/expandenv/expand_env.go (about)

     1  // Package expandenv replaces ${key} in byte slices with the env value of key.
     2  package expandenv
     3  
     4  import (
     5  	"os"
     6  )
     7  
     8  // ExpandEnv looks for ${var} in s and replaces them with value of the corresponding environment variable.
     9  // It's not like os.ExpandEnv which handles both ${var} and $var.
    10  // $var is considered invalid, since configurations like password for redis/mysql may contain $.
    11  func ExpandEnv(s []byte) []byte {
    12  	var buf []byte
    13  	i := 0
    14  	for j := 0; j < len(s); j++ {
    15  		if s[j] == '$' && j+2 < len(s) && s[j+1] == '{' { // only ${var} instead of $var is valid
    16  			if buf == nil {
    17  				buf = make([]byte, 0, 2*len(s))
    18  			}
    19  			buf = append(buf, s[i:j]...)
    20  			name, w := getEnvName(s[j+1:])
    21  			if name == nil && w > 0 {
    22  				// invalid matching, remove the $
    23  			} else if name == nil {
    24  				buf = append(buf, s[j]) // keep the $
    25  			} else {
    26  				buf = append(buf, os.Getenv(string(name))...)
    27  			}
    28  			j += w
    29  			i = j + 1
    30  		}
    31  	}
    32  	if buf == nil {
    33  		return s
    34  	}
    35  	return append(buf, s[i:]...)
    36  }
    37  
    38  // getEnvName gets env name, that is, var from ${var}.
    39  // The env name and its len will be returned.
    40  func getEnvName(s []byte) ([]byte, int) {
    41  	// look for right curly bracket '}'
    42  	// it's guaranteed that the first char is '{' and the string has at least two char
    43  	for i := 1; i < len(s); i++ {
    44  		if s[i] == ' ' || s[i] == '\n' || s[i] == '"' { // "xx${xxx"
    45  			return nil, 0 // encounter invalid char, keep the $
    46  		}
    47  		if s[i] == '}' {
    48  			if i == 1 { // ${}
    49  				return nil, 2 // remove ${}
    50  			}
    51  			return s[1:i], i + 1
    52  		}
    53  	}
    54  	return nil, 0 // no },keep the $
    55  }