cmd/drover: ReElevate — surface UTF16 + Getwd errors, escape quotes
Build / test (push) Failing after 33s
Build / build-windows (push) Has been skipped

Code review found 5 silently-ignored errors in ReElevate (UTF16
conversions and os.Getwd) plus unescaped argument quoting that
breaks args containing literal `"`. Each error is now wrapped with
a clear message; quotes are backslash-escaped per the MSVC argv
convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 19:38:05 +03:00
parent 8e83260123
commit 11de3fb12b
2 changed files with 29 additions and 10 deletions
+26 -7
View File
@@ -3,7 +3,9 @@
package main package main
import ( import (
"fmt"
"os" "os"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
@@ -59,15 +61,23 @@ func ReElevate(args []string) error {
if err != nil { if err != nil {
return err return err
} }
verb, _ := syscall.UTF16PtrFromString("runas") verb, err := syscall.UTF16PtrFromString("runas")
exePtr, _ := syscall.UTF16PtrFromString(exe) if err != nil {
return fmt.Errorf("encode verb: %w", err)
}
exePtr, err := syscall.UTF16PtrFromString(exe)
if err != nil {
return fmt.Errorf("encode exe: %w", err)
}
var paramsPtr *uint16 var paramsPtr *uint16
if len(args) > 0 { if len(args) > 0 {
// Quote each arg in case of spaces. // Quote each arg in case of spaces, and escape internal quotes.
quoted := make([]string, len(args)) quoted := make([]string, len(args))
for i, a := range args { for i, a := range args {
quoted[i] = `"` + a + `"` // Escape any internal quotes with backslash (MSVC argv convention).
escaped := strings.ReplaceAll(a, "\"", "\\\"")
quoted[i] = `"` + escaped + `"`
} }
joined := "" joined := ""
for i, q := range quoted { for i, q := range quoted {
@@ -76,11 +86,20 @@ func ReElevate(args []string) error {
} }
joined += q joined += q
} }
paramsPtr, _ = syscall.UTF16PtrFromString(joined) paramsPtr, err = syscall.UTF16PtrFromString(joined)
if err != nil {
return fmt.Errorf("encode params: %w", err)
}
} }
cwd, _ := os.Getwd() cwd, err := os.Getwd()
cwdPtr, _ := syscall.UTF16PtrFromString(cwd) if err != nil {
return fmt.Errorf("get cwd: %w", err)
}
cwdPtr, err := syscall.UTF16PtrFromString(cwd)
if err != nil {
return fmt.Errorf("encode cwd: %w", err)
}
// SW_NORMAL = 1 // SW_NORMAL = 1
return windows.ShellExecute(0, verb, exePtr, paramsPtr, cwdPtr, 1) return windows.ShellExecute(0, verb, exePtr, paramsPtr, cwdPtr, 1)
+3 -3
View File
@@ -16,12 +16,12 @@ func TestCmdNeedsAdmin_NoAdminFlags(t *testing.T) {
args []string args []string
needsAdm bool needsAdm bool
}{ }{
{[]string{}, true}, // bare drover.exe → GUI mode → needs admin {[]string{}, true}, // bare drover.exe → GUI mode → needs admin
{[]string{"check"}, false}, // diagnostic only, no driver {[]string{"check"}, false}, // diagnostic only, no driver
{[]string{"check", "--host", "x"}, false}, {[]string{"check", "--host", "x"}, false},
{[]string{"--version"}, false}, {[]string{"--version"}, false},
{[]string{"version"}, false}, {[]string{"version"}, false},
{[]string{"update"}, false}, // self-update doesn't need driver {[]string{"update"}, false}, // self-update doesn't need driver
} }
for _, c := range cases { for _, c := range cases {
got := CmdNeedsAdmin(c.args) got := CmdNeedsAdmin(c.args)