Skip to content

Single-rune Unicode flags can be emitted by completion but not parsed #2433

Description

@znnnnnnn-wil

My urfave/cli version is

v3.12.0 (9b981a04295de5121091c479f8a7a0476d2e8d38)

Checklist

  • I am running the latest v3 release.
  • I checked the v3 manual.
  • I searched existing issues and pull requests for this problem.

Dependency Management

  • My project is using Go modules.

Describe the bug

Single-rune Unicode flag names are handled inconsistently. Shell completion counts runes and emits a single-dash flag such as , but help formatting counts bytes and displays --ש. More importantly, the parser examines rune(firstArg[1]), which converts only the first UTF-8 byte rather than decoding the first rune.

For ש, the first byte is 0xD7; converting that byte to a rune produces ×, which is not a letter. The parser therefore classifies as a positional argument and never sets the registered flag.

To reproduce

package main

import (
    "context"
    "fmt"

    "github.com/urfave/cli/v3"
)

func main() {
    const name = "ש"
    cmd := &cli.Command{
        Name:  "app",
        Flags: []cli.Flag{&cli.StringFlag{Name: name}},
        Action: func(_ context.Context, cmd *cli.Command) error {
            fmt.Printf("value=%q args=%q\n", cmd.String(name), cmd.Args().Slice())
            return nil
        },
    }
    _ = cmd.Run(context.Background(), []string{"app", "-" + name, "value", "operand"})
}

Observed behavior

value="" args=["-ש" "value" "operand"]

Help formatting also prefixes this single-rune name with --, while flag completion uses -.

Expected behavior

A one-rune Unicode flag should be treated consistently with a one-byte ASCII flag:

value="value" args=["operand"]

Help and completion should both render it as .

Additional context

prefixFor uses len(name) == 1, while completion already uses utf8.RuneCountInString. In parseFlags, decoding the first rune after the leading dash instead of converting firstArg[1] would preserve existing ASCII behavior and correctly classify Unicode letters.

Want to fix this yourself?

Yes. The fix is small and can be covered by a focused regression test.

Run go version and paste its output here

go version go1.26.5 windows/amd64

Relevant go env output

GOOS=windows
GOARCH=amd64
GOVERSION=go1.26.5
CGO_ENABLED=0

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions