diff --git a/windows/exec_windows.go b/windows/exec_windows.go index 75980fd44..a52e0331d 100644 --- a/windows/exec_windows.go +++ b/windows/exec_windows.go @@ -95,12 +95,17 @@ func ComposeCommandLine(args []string) string { // DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv, // as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that // command lines are passed around. +// DecomposeCommandLine returns error if commandLine contains NUL. func DecomposeCommandLine(commandLine string) ([]string, error) { if len(commandLine) == 0 { return []string{}, nil } + utf16CommandLine, err := UTF16FromString(commandLine) + if err != nil { + return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine") + } var argc int32 - argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc) + argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc) if err != nil { return nil, err } diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index c72c788f0..42c01fc96 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -626,6 +626,22 @@ func TestCommandLineRecomposition(t *testing.T) { continue } } + + // check that windows.DecomposeCommandLine returns error for strings with NUL + testsWithNUL := []string{ + "\x00abcd", + "ab\x00cd", + "abcd\x00", + "\x00abcd\x00", + "\x00ab\x00cd\x00", + "\x00\x00\x00", + } + for _, test := range testsWithNUL { + _, err := windows.DecomposeCommandLine(test) + if err == nil { + t.Errorf("Failed to return error while decomposing %#q string with NUL inside", test) + } + } } func TestWinVerifyTrust(t *testing.T) {