Commit f18a4e96 authored by Vincent Vanackere's avatar Vincent Vanackere Committed by Russ Cox

syscall : add ProcAttr field to pass an unescaped command line on windows

On windows, the command line is passed as a single null-terminated string. While the automatic parameter escaping done by syscall.StartProcess works fine with most Windows programs, some applications do their own custom parsing of the command line, in which case the automatic escaping becomes harmful.
This CL adds a new extra CmdLine field to syscall.ProcAttr that will be used as the raw/unescaped command line if not empty.
Fixes #1849.

R=golang-dev, alex.brainman, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/4548050
parent c4206cb2
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
var ForkLock sync.RWMutex var ForkLock sync.RWMutex
// escape rewrites command line argument s as prescribed // EscapeArg rewrites command line argument s as prescribed
// in http://msdn.microsoft.com/en-us/library/ms880421. // in http://msdn.microsoft.com/en-us/library/ms880421.
// This function returns "" (2 double quotes) if s is empty. // This function returns "" (2 double quotes) if s is empty.
// Alternatively, these transformations are done: // Alternatively, these transformations are done:
...@@ -23,7 +23,7 @@ var ForkLock sync.RWMutex ...@@ -23,7 +23,7 @@ var ForkLock sync.RWMutex
// - every double quote (") is escaped by back slash (\); // - every double quote (") is escaped by back slash (\);
// - finally, s is wrapped with double quotes (arg -> "arg"), // - finally, s is wrapped with double quotes (arg -> "arg"),
// but only if there is space or tab inside s. // but only if there is space or tab inside s.
func escape(s string) string { func EscapeArg(s string) string {
if len(s) == 0 { if len(s) == 0 {
return "\"\"" return "\"\""
} }
...@@ -89,7 +89,7 @@ func makeCmdLine(args []string) string { ...@@ -89,7 +89,7 @@ func makeCmdLine(args []string) string {
if s != "" { if s != "" {
s += " " s += " "
} }
s += escape(v) s += EscapeArg(v)
} }
return s return s
} }
...@@ -222,6 +222,7 @@ type ProcAttr struct { ...@@ -222,6 +222,7 @@ type ProcAttr struct {
Env []string Env []string
Files []int Files []int
HideWindow bool HideWindow bool
CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
} }
var zeroAttributes ProcAttr var zeroAttributes ProcAttr
...@@ -252,10 +253,19 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int, ...@@ -252,10 +253,19 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int,
} }
argv0p := StringToUTF16Ptr(argv0) argv0p := StringToUTF16Ptr(argv0)
var cmdline string
// Windows CreateProcess takes the command line as a single string:
// use attr.CmdLine if set, else build the command line by escaping
// and joining each argument with spaces
if attr.CmdLine != "" {
cmdline = attr.CmdLine
} else {
cmdline = makeCmdLine(argv)
}
var argvp *uint16 var argvp *uint16
s := makeCmdLine(argv) if len(cmdline) != 0 {
if len(s) != 0 { argvp = StringToUTF16Ptr(cmdline)
argvp = StringToUTF16Ptr(s)
} }
var dirp *uint16 var dirp *uint16
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment