diffplug / diffplug/dormouse

quoteCmdArg corrupts arguments containing a literal `"` on cmd surfaces

Đang mở
#162 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
TypeScript
Star
5
Fork
0
Merge trung bình
18 giờ 32 phút
Pull request đã merge (30 ngày)
216

Mô tả

## `quoteCmdArg` corrupts arguments containing a literal `"` on cmd surfaces

When `dor` forwards a command tail (`dor split -- …`, `dor ensure …`) to a pane whose shell is `cmd.exe`, the host renders the argv with [`quoteCmdArg`](https://github.com/diffplug/dormouse/blob/7f88741dadf837a4711d4c725b6f8a9977c496cc/dor/src/commands/shell-quote.ts#L54-L61). For any argument that contains a double-quote, the output is malformed.

### Trace

```ts
function quoteCmdArg(arg: string): string {
if (arg === '') return '""';
const escaped = arg
.replace(/[%]/g, '%%')
.replace(/([&|<>()^"])/g, '^$1'); // caret-escapes the "
if (WINDOWS_SAFE_ARG.test(arg)) return escaped;
return `"${escaped}"`; // ...then wraps the result in quotes
}
```

For `arg = 'say "hi"'` the function:
1. caret-escapes each `"` → `say ^"hi^"`, then
2. wraps in surrounding quotes → `"say ^"hi^""`.

Inside a cmd double-quoted region, `^` is **not** an escape character — it is literal. So the embedded `^"` does not produce an escaped quote; the first `^"` is read as a literal `^` followed by a quote that **closes** the surrounding quoted region early, and the rest of the argument is re-parsed outside quotes. The argument the launched program receives is not `say "hi"`.

The same belt-and-suspenders pattern (caret-escape *and* wrap in quotes) is what the existing test pins for `a&b` → `"a^&b"` ([cli-output.test.mjs:204-206](https://github.com/diffplug/dormouse/blob/7f88741dadf837a4711d4c725b6f8a9977c496cc/dor/test/cli-output.test.mjs#L204-L206)); for `&`/`(`/`)` the caret inside quotes is merely redundant (those chars are already literal inside quotes), so it's harmless-but-odd. For `"` it is actively wrong, and that case is **untested**.

### Why this needs maintainer input rather than a drive-by fix

Correct cmd-line quoting for a literal `"` depends on how the *receiving* program parses its command line (the msvcrt/`CommandLineToArgvW` convention uses `\"` and `""`; a bare cmd builtin differs). Picking the right escaping is a design decision that should be validated on an actual Windows + cmd.exe host, which this CI environment can't do. Flagging rather than guessing.

### Suggested direction (needs Windows verification)

For the `cmd` kind, escape an embedded `"` by doubling it (`""`) or backslash-escaping (`\"`) *inside* the wrapped form, and don't caret-escape characters that already sit inside the surrounding quotes. Add a `cli-output.test.mjs` case with an embedded `"` to pin whatever behavior is chosen.

_Surfaced by the nightly code-quality survey._

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Bắt đầu tại dor/src/commands/shell-quote.ts, ở quoteCmdArg, và xem lại các kỳ vọng hiện có trong dor/test/cli-output.test.mjs quanh các dòng 204-206. Xác thực hành vi dấu ngoặc kép nguyên văn đã chọn trên một host Windows cmd.exe, sau đó thêm một trường hợp hồi quy có dấu ngoặc kép được nhúng và xác nhận rằng chương trình được khởi chạy nhận được đối số ban đầu.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
typescript
Lĩnh vực
cli
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.