Skip to content

fix: preserve whitespace in positional arguments - #2423

Open
lenamonj wants to merge 1 commit into
urfave:mainfrom
lenamonj:fix-positional-whitespace
Open

fix: preserve whitespace in positional arguments#2423
lenamonj wants to merge 1 commit into
urfave:mainfrom
lenamonj:fix-positional-whitespace

Conversation

@lenamonj

Copy link
Copy Markdown

parseFlags computes firstArg := strings.TrimSpace(rargs[0]) to classify each argument, which is correct - but the positional branch then stores the trimmed copy instead of the original argument, so any positional carrying deliberate whitespace is silently rewritten:

cmd := &cli.Command{Name: "prog", Action: ...}
cmd.Run(ctx, []string{"prog", "  padded  "})
// cmd.Args().Slice() == ["padded"], not ["  padded  "]

A filename with a leading space, a message string, a pattern argument - all reach the action modified, with no error. The empty-string branch a few lines above already appends rargs[0] untrimmed, so this change makes the non-empty branch consistent with its sibling: classify with the trimmed copy, append the original.

One line changed in command_parse.go, plus a regression test.

Note: the lone-- branch nearby has the same trimmed append, but that line is already being rewritten by #2419 (the bare-dash fix), so this PR deliberately does not touch it.

@lenamonj
lenamonj requested a review from a team as a code owner August 30, 2026 23:17
@abitrolly

Copy link
Copy Markdown
Contributor

@lenamonj can you give the usage example of the real CLI interface that you are trying to fix?

Shell doesn't allow me to enter tab into CLI, needless to say it won't split it.

@avorima

avorima commented Aug 31, 2026

Copy link
Copy Markdown

@abitrolly It works by quoting the input

./prog " quoted string with spaces "

I personally use this for curl, for example when providing some ad-hoc JSON

curl ... -d '{
// paste multiple lines
// of JSON
}
' # close quoted string and send to curl with whitespace intact

@lenamonj

Copy link
Copy Markdown
Author

Sure - quoting is how the whitespace gets in, as @avorima says. The case
that bit me is a filename that legally contains a leading or trailing space:

touch " notes.txt"
mytool cat " notes.txt"

Before this change the action receives "notes.txt" with the space stripped, so the open fails with a confusing "no such file" for a file that plainly exists. Same shape for any argument where whitespace is content rather than separator - a search pattern of two spaces, or a message string built by a
calling script:

mytool search "  "     # looks for two spaces, receives ""

The parser is right to trim when classifying the token (deciding flag vs
positional); the bug is that it then stored the trimmed copy instead of the
original.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants