util: parseArgs() treats a `-` inside a short option group as the `--` terminator
维护者通常 1 天内回复
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 75/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- javascript, nodejs
- 领域
- cli
调研方向
从 lib/internal/util/parse_args/parse_args.js 中的 argsToTokens() 开始,这里会展开形如 -a-b 的短选项组,并将其重新压回参数列表。检查循环中 arg === '--' 判断与组计数器的先后顺序,确保合成的 -- 不会被当作真正的终止符。分别在 strict 和非 strict 模式下运行 issue 中的复现代码,并加上 tokens: true,确认 -a-b 会产生未知选项错误,且每个 token 的 index 与其来源参数的位置一致。当现有 parseArgs 测试全部通过,并且新增用例覆盖 -a-b 和 -a- 时,即完成。
由索引模型根据 Issue 内容生成。
描述
Version
v28.0.0-pre (main, d2812af0), also v22.20.0
Platform
Linux 7.0.0-38-generic x86_64
Subsystem
util
What steps will reproduce the bug?
const { parseArgs } = require('node:util');
const options = { a: { type: 'boolean' }, b: { type: 'boolean' } };
// Non-strict, with tokens.
const args = ['-a-b', 'pos'];
const { values, positionals, tokens } = parseArgs({
args, options, strict: false, allowPositionals: true, tokens: true,
});
console.log(values, positionals);
for (const token of tokens) {
console.log(token, '-> args[index] =', args[token.index]);
}
// Strict.
for (const arg of ['-a-b', '-a-']) {
try {
parseArgs({ args: [arg], options });
console.log(arg, 'ok');
} catch (err) {
console.log(arg, err.code, '-', err.message);
}
}
How often does it reproduce? Is there a required condition?
Every time. Needs a - character inside a short option group, for example -a-b or -a-.
What is the expected behavior?
- is not a valid option character, so -a-b should be reported the same way as any other unknown short option in a group (compare -ar with r unknown). In strict mode that is ERR_PARSE_ARGS_UNKNOWN_OPTION. With tokens: true, every token's index should point at the argument it came from, as the docs say: "the source argument for a token is args[token.index]".
What do you see instead?
[Object: null prototype] { a: true } [ '-b', 'pos' ]
{ kind: 'option', name: 'a', rawName: '-a', index: 0, value: undefined, inlineValue: undefined } -> args[index] = -a-b
{ kind: 'option-terminator', index: 0 } -> args[index] = -a-b
{ kind: 'positional', index: 1, value: '-b' } -> args[index] = pos
{ kind: 'positional', index: 2, value: 'pos' } -> args[index] = undefined
-a-b ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL - Unexpected argument '-b'. This command does not take positional arguments
-a- ok
-bbecomes a positional instead of an option.- An
option-terminatortoken appears although the user never passed--. - The positional indexes are shifted by one, so
args[token.index]is the wrong argument orundefined. - In strict mode
-a-breports a misleading unexpected-positional error, and-a-is accepted silently.
Additional information
argsToTokens() in lib/internal/util/parse_args/parse_args.js expands a short option group -a-b into -a, --, -b and pushes them back onto the argument list. The loop then checks arg === '--' before it looks at whether the argument came from a group, so the synthesized -- is handled as the real terminator. The group counter (groupCount) already knows the argument was expanded.
For comparison, getopt(3) reports -a-b as invalid option -- '-'.
I have a small fix with tests and can open a PR.
- 主要语言
- JavaScript
- 星标
- 123k
- 派生
- 39.3k
- 平均合并
- 4 天 15 小时
- 30 天内合并 PR
- 238
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
nodejs/node 的其他 Issue
-
http2: content-encoding is incorrectly listed in kSingleValueHeaders可能已有人在做 @inoway46 于 2 天前认领。 未关闭confirmed-bug http2
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
util.parseEnv and --env-file keep a leading UTF-8 BOM in the first key可能已有人在做 @helmipradita 于 4 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
node:internal/inspector/network_http: `TypeError: Missing dataLength` in event when response uses `setEncoding()`可能重新可做 关联的 PR 已关闭且未合并。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
[Docs] `process.loadEnvFile()` does not document behaviour when variables already exist可能已有人在做 @Sepandard 于 38 天前认领。 未关闭doc
难度 1/5 1 小时以内 新手友好度 90/100
维护者通常 1 天内回复
-
Stream.prototype.forEach will block in first promise in queue before read more chunk可能已有人在做 @mmustafasenoglu 于 39 天前认领。 未关闭doc
难度 2/5 1-3 小时 新手友好度 65/100
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 66/100
riverqueue/river#1576 ·
维护者通常 1 天内回复
-
documentation good first issue
难度 1/5 1 小时以内 新手友好度 72/100
维护者通常 1 天内回复
-
good first issue help wanted
难度 1/5 1 小时以内 新手友好度 88/100
modrollstudio/Modroll-Studio-Website#80 · 1 条评论 ·
维护者通常 1 天内回复
-
good first issue help wanted
难度 2/5 1-3 小时 新手友好度 85/100
mafzalkalwardev/mailforge#21 ·
-
good first issue help wanted
难度 1/5 1 小时以内 新手友好度 82/100