Skip to content

fix(cli): recognize --flag=value form in startup arg pre-scan#144

Open
Episkey-G wants to merge 1 commit into
masterfrom
fix/global-flag-equals-form
Open

fix(cli): recognize --flag=value form in startup arg pre-scan#144
Episkey-G wants to merge 1 commit into
masterfrom
fix/global-flag-equals-form

Conversation

@Episkey-G

Copy link
Copy Markdown
Collaborator

问题

cmd/root.goinit() 在 cobra 解析之前手写扫描 os.Args,把连接类参数落到 global.*(时序约束:这些参数须在 InitClientRuntime 构造 sdk.Config 前定型)。但扫描用精确比较 arg == "--base-url",只匹配空格形式:

  • --base-url X(两个 argv)→ 匹配 ✅
  • --base-url=X(一个 argv)→ 不匹配,被静默无视

受影响:--base-url--profile(含短选项 -p)、--public-key--private-key--channel-key--timeout-sec--max-retry-times

这不是新 bug — issue #119 已为一个 flag 修过

parseWaitTimeoutSecroot.go)用 strings.CutPrefix(arg, flag+"=") 已是双形式模板,并有表驱动测试 TestParseWaitTimeoutSec。其余 flag 当年没跟着改。本 PR 把该修复推广开。

--profile=X / -p X 是安全问题

platform/client.go 注释已载明:扫描漏识别 -p X/--profile=X → ConfigIns 指向另一个 profile → OAuth token 刷新可能把别人的 Bearer 重放到当前请求。讽刺的是 config 命令的官方 Example 就写着 --profile=test

实测:今天这些形式操作的是错误的 profile

两个 profile(default 活动 / prod 非活动,base_url 各不同),命令意图操作 prod:

形式 master(现状) 本 PR 变化
(无 --profile default default 零变化(最常见)
--profile prod(空格) prod prod 零变化(最常用显式写法)
--profile=prod(等号) default ← 错 prod 修复
-p prod(短选项空格) default ← 错 prod 修复
-p=prod(短等号) default ← 错 prod 修复

注意 -p prod:文档明载的短选项,今天操作的却是 default 而非 prod。用户跑 ucloud uhost list -p prod 拿到的是 default 的列表。这不是「打断正常使用」,是纠正一个一直在悄悄用错 profile 的写法。

方案

抽通用 helper scanFlagValue(args, names...)(模仿 parseWaitTimeoutSec,支持 --profile/-p 多别名),识别 name valuename=value 两形式,空值视为未命中。init() 的 7 处精确比较扫描全部改为调它。

附着/组合短选项(-pfoo-dpfoo)有意不处理:手工解析组合短选项易错,且其残留风险与现状持平(现状 -p 任何形式都不早识别)。TestScanFlagValue-pfoo → ("", false) 守住该边界。

parseWaitTimeoutSec 及其 #119 测试保留不动。

测试

  • TestScanFlagValue(10 用例):长/短 × 空格/等号、空值、末尾无值、附着不识别、多别名、靠前优先。
  • 既有 TestParseWaitTimeoutSec 仍绿。
  • 全量回归 go test ./... 全绿,go vet 干净。
  • 端到端:上表即真实二进制实测(master vs 本 PR)。--base-url=X 亦实测:master 无视、照打旧地址,本 PR 生效。
  • 变异测试:去掉 = 识别,等号用例立刻红 → 证明测试守护该修复。

⚠️ CI 的 test job 不含 ./cmd/...pr-gate.yml),本 PR 用例 CI 不跑,请本地 go test ./cmd/... -count=1

行为变更(需入发版说明)

--flag=value 等号形式此前静默失效、现生效。尤其:

若你用过 --profile=X-p X-p=X,此前因 bug 它们实际操作默认 profile;现已修正为操作 X。请核对脚本是否指向预期 profile。

空格形式(--flag value)与不带 flag 的行为零变化。属安全修复(消除 profile/Bearer 错配窗口)+ 能力恢复(等号形式生效)。

不在本 PR 范围

root.go init() 的启动期 os.Args 预扫描用精确比较 arg=="--base-url",只匹配
空格形式,漏识别 --base-url=X / --profile=X / -p X 等形式。连接类参数因此在
InitClientRuntime 构造 sdk.Config 前未生效:--base-url=X 被无视、照打旧地址。

--profile=X / -p X 尤其是安全问题:ConfigIns 指向错误 profile,OAuth token
刷新可能把别人的 Bearer 重放到当前请求(platform/client.go 已载明)。讽刺的是
config 命令的官方 Example 就写着 --profile=test,工具用了自己处理不了的形式。

这是 issue #119 为 --wait-timeout-sec 修过的同一个 bug;parseWaitTimeoutSec
用 strings.CutPrefix 已是双形式模板,其余 flag 当年没跟着改。本次抽通用 helper
scanFlagValue(args, names...)(支持 --profile/-p 多别名),替换 init() 7 处精确
比较扫描。附着/组合短选项(-pfoo/-dpfoo)有意不处理(手工解析组合短选项易错,
残留风险与现状持平),TestScanFlagValue 用 -pfoo→("",false) 守住该边界。

不含 -h/resetHelpFunc(用户裁定不改)。--profile=X 行为变更(静默失效→真正
生效)需入发版说明。CI 不跑 ./cmd/,用例须本地跑。
@github-actions

Copy link
Copy Markdown

🔴 平台 PR 默认硬拦,需管理员 Approve 放行(或由管理员提交)。判定:改动触及平台/受保护路径(cmd/root.go, cmd/root_test.go)

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.

1 participant