Source file src/cmd/go/internal/envcmd/env_test.go

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build unix || windows
     6  
     7  package envcmd
     8  
     9  import (
    10  	"bytes"
    11  	"cmd/go/internal/cfg"
    12  	"fmt"
    13  	"internal/testenv"
    14  	"os"
    15  	"os/exec"
    16  	"path/filepath"
    17  	"runtime"
    18  	"testing"
    19  	"unicode"
    20  )
    21  
    22  func FuzzPrintEnvEscape(f *testing.F) {
    23  	f.Add(`$(echo 'cc"'; echo 'OOPS="oops')`)
    24  	f.Add("$(echo shell expansion 1>&2)")
    25  	f.Add("''")
    26  	f.Add(`C:\"Program Files"\`)
    27  	f.Add(`\\"Quoted Host"\\share`)
    28  	f.Add("\xfb")
    29  	f.Add("0")
    30  	f.Add("")
    31  	f.Add("''''''''")
    32  	f.Add("\r")
    33  	f.Add("\n")
    34  	f.Add("E,%")
    35  	f.Fuzz(func(t *testing.T, s string) {
    36  		t.Parallel()
    37  
    38  		for _, c := range []byte(s) {
    39  			if c == 0 {
    40  				t.Skipf("skipping %q: contains a null byte. Null bytes can't occur in the environment"+
    41  					" outside of Plan 9, which has different code path than Windows and Unix that this test"+
    42  					" isn't testing.", s)
    43  			}
    44  			if c > unicode.MaxASCII {
    45  				t.Skipf("skipping %#q: contains a non-ASCII character %q", s, c)
    46  			}
    47  			if !unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c)) {
    48  				t.Skipf("skipping %#q: contains non-graphic character %q", s, c)
    49  			}
    50  			if runtime.GOOS == "windows" && c == '\r' || c == '\n' {
    51  				t.Skipf("skipping %#q on Windows: contains unescapable character %q", s, c)
    52  			}
    53  		}
    54  
    55  		var b bytes.Buffer
    56  		if runtime.GOOS == "windows" {
    57  			b.WriteString("@echo off\n")
    58  		}
    59  		PrintEnv(&b, []cfg.EnvVar{{Name: "var", Value: s}})
    60  		var want string
    61  		if runtime.GOOS == "windows" {
    62  			fmt.Fprintf(&b, "echo \"%%var%%\"\n")
    63  			want += "\"" + s + "\"\r\n"
    64  		} else {
    65  			fmt.Fprintf(&b, "printf '%%s\\n' \"$var\"\n")
    66  			want += s + "\n"
    67  		}
    68  		scriptfilename := "script.sh"
    69  		if runtime.GOOS == "windows" {
    70  			scriptfilename = "script.bat"
    71  		}
    72  		var cmd *exec.Cmd
    73  		if runtime.GOOS == "windows" {
    74  			scriptfile := filepath.Join(t.TempDir(), scriptfilename)
    75  			if err := os.WriteFile(scriptfile, b.Bytes(), 0777); err != nil {
    76  				t.Fatal(err)
    77  			}
    78  			cmd = testenv.Command(t, "cmd.exe", "/C", scriptfile)
    79  		} else {
    80  			cmd = testenv.Command(t, "sh", "-c", b.String())
    81  		}
    82  		out, err := cmd.Output()
    83  		t.Log(string(out))
    84  		if err != nil {
    85  			t.Fatal(err)
    86  		}
    87  
    88  		if string(out) != want {
    89  			t.Fatalf("output of running PrintEnv script and echoing variable: got: %q, want: %q",
    90  				string(out), want)
    91  		}
    92  	})
    93  }
    94  

View as plain text