Skip to content

Fix panic on a set tag without a value - #623

Open
chuenchen309 wants to merge 1 commit into
alecthomas:masterfrom
chuenchen309:fix/set-tag-missing-equals
Open

Fix panic on a set tag without a value#623
chuenchen309 wants to merge 1 commit into
alecthomas:masterfrom
chuenchen309:fix/set-tag-missing-equals

Conversation

@chuenchen309

Copy link
Copy Markdown
Contributor

A set tag without a = crashes the program instead of returning the error kong already wrote for it.

The guard contradicts its own next line:

parts := strings.SplitN(set, "=", 2)
if len(parts) == 0 {
    return fmt.Errorf("set should be in the form key=value but got %q", set)
}
t.Vars[parts[0]] = parts[1]

strings.SplitN never returns a zero-length slice, so len(parts) == 0 is dead code and parts[1] indexes a length-1 slice whenever the tag has no =.

Reproduction

var cli struct {
    Flag string `set:"novalue"`
}
_, err := kong.New(&cli)
panic: runtime error: index out of range [1] with length 1

For comparison, another malformed tag on a sibling path returns cleanly, and the well-formed case is unaffected:

Flag string `set:"novalue"`   ->  panic: index out of range [1] with length 1
Flag string `short:"ab"`      ->  error: <anonymous struct>.Flag: invalid short flag name "ab": invalid rune
Flag string `set:"k=v"`       ->  nil

The README documents the tag as set:"K=V", so a missing = is an ordinary typo, and it reaches this through kong.New / kong.Must / kong.Parse.

Fix

Compare against len(parts) != 2, so the message on the line above can actually fire:

<anonymous struct>.Flag: set should be in the form key=value but got "novalue"

Added TestTagSetWithoutValueErrors alongside TestInvalidRuneErrors, which is the same shape. go test ./... passes; go vet reports the same 78 pre-existing struct-tag warnings as on master.


Disclosure: this was found, written and verified by an AI coding agent (Claude Code) running on this account — the commit carries a Co-Authored-By trailer for it. The outputs above came from running the code, not reading it, but the agent ran them, not a person. Happy to adjust anything.

The guard contradicts its own next line:

    parts := strings.SplitN(set, "=", 2)
    if len(parts) == 0 {
        return fmt.Errorf("set should be in the form key=value but got %q", set)
    }
    t.Vars[parts[0]] = parts[1]

SplitN never returns a zero-length slice, so the check is dead and parts[1]
indexes a length-1 slice whenever the tag has no "=":

    Flag string `set:"novalue"`   -> panic: index out of range [1] with length 1
    Flag string `short:"ab"`      -> error: invalid short flag name "ab": invalid rune
    Flag string `set:"k=v"`       -> nil

The error message on the line above already says exactly what should happen --
it just could not fire. Another malformed tag on a sibling path returns
cleanly, so this is the odd one out.

README documents the tag as set:"K=V", so a missing "=" is an ordinary typo,
and it reaches this through kong.New / kong.Must / kong.Parse.

Compare against len(parts) != 2 so the intended error is returned.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants