Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flag: fails to parse flags with particularly-placed (but valid) double-quotes inside executable path #43054

Open
liquidaty opened this issue Dec 7, 2020 · 5 comments

Comments

@liquidaty
Copy link

@liquidaty liquidaty commented Dec 7, 2020

What version of Go are you using (go version)?

go version go1.15.2 darwin/amd64, cross-compiling for and running on win

I noticed this issue after cross-compiling for win, then running on win. I have only been able to reproduce on Win. I have not tried compiling natively on win to see if the issue also exists under those circumstances

Does this issue reproduce with the latest release?

What operating system and processor architecture are you using (go env)?

Host (build):
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/mattewong/Library/Caches/go-build"
GOENV="/Users/mattewong/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/mattewong/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/mattewong/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/3d/4_23s9qj7dj3z966y7_q__hm0000gp/T/go-build380736401=/tmp/go-build -gno-record-gcc-switches -fno-common"

Target (run): Windows Server 2016

What did you do?

flag_bug.go:

/*
  demo of flag bug
*/
package main

import (
        "flag"
        "log"
)


func main() {
        stringVar := "default string value"
        flag.StringVar(&stringVar, "str", stringVar, "set a string var")
        flag.Parse()
        log.Printf("String var: %s\n", stringVar)
}

compile:
GOOS=windows go build flag_bug.go

copy flag_bug.exe to target system c:\temp\

run:

  1. flag_bug.exe -h
  2. "c:\temp"\flag_bug.exe -h
  3. "c:\temp\"flag_bug.exe -h

What did you expect to see?

Same result each time: usage

What did you see instead?

First 2 behave as expected:

Usage of flag_bug.exe:
  -str string
        set a string var (default "default string value")

However, the third one ("c:\temp\"flag_bug.exe -h) does not:

2020/12/07 20:10:22 String var: default string value

It appears that the double-quotes somehow cause the flag parsing to entirely fail, and no flags are parsed (whether expected flags or not)

@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Dec 7, 2020

For some more context, this only happens with cmd.exe
"c:\temp\"flag_bug.exe -h is invalid in powershell

The terminal interprets \" to mean a literal " so the quoting is technically invalid.
os.Args reports args as [c:\temp"flag_bug.exe -h]
So there might be something fixable in Go but I'm not sure if that would happen.

Loading

@liquidaty
Copy link
Author

@liquidaty liquidaty commented Dec 7, 2020

The terminal interprets \" to mean a literal " so the quoting is technically invalid.

I do not believe this statement is correct. It may be true in powershell, but it is definitely not true in cmd.exe which has no problem finding and executing the binary. If it was true, then the OS would be looking for a file called temp"flag_bug.exe located in C: and it would fail with a file-not-found error.

This behavior is, I believe, documented at https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?redirectedfrom=MSDN&view=msvc-160 (my emphasis added):

The first argument (argv[0]) is treated specially. It represents the program name. Because it must be a valid pathname, parts surrounded by double quote marks (") are allowed. The double quote marks aren't included in the argv[0] output. The parts surrounded by double quote marks prevent interpretation of a space or tab character as the end of the argument. The later rules in this list don't apply.

It is only in a "later rule"-- which explicitly does not apply to argv[0]-- that it then states: "A double quote mark preceded by a backslash (\") is interpreted as a literal double quote mark (")."

Even if this is a known issue that will not be fixed, I have to disagree with the suggestion that this isn't a bug. "my program is running and it cannot find the flags I passed to it" is a bug, regardless of what the technical reasons are for it existing. It would be a different thing if Windows itself interpreted it the way you've suggested, and therefore windows was unable to find and execute the exe. However, that is not the case.

Loading

@liquidaty
Copy link
Author

@liquidaty liquidaty commented Dec 7, 2020

BTW I recognize that the bug may not from the flags lib directly-- based on your comment that os.Args is c:\temp"flag_bug.exe, the bug likely resides there

Loading

@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Dec 7, 2020

Thanks for the link to the docs.
The C program does indeed show arg[0] to be c:\temp\flag_bug.exe

ping as per os owners @rsc @robpike @ianlancetaylor @bradfitz @griesemer

Loading

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Dec 7, 2020

Loading

@ianlancetaylor ianlancetaylor added this to the Backlog milestone Dec 7, 2020
@seankhliao seankhliao changed the title "flag" library fails to parse flags with particularly-placed (but valid) double-quotes inside executable path flag: fails to parse flags with particularly-placed (but valid) double-quotes inside executable path Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants