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

オープン
#162 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
typescript
領域
cli

調査の方向性

dor/src/commands/shell-quote.ts の quoteCmdArg から始め、dor/test/cli-output.test.mjs の 204-206 行付近にある既存の期待値を確認してください。Windows cmd.exe ホスト上で、選択したリテラル引用符の動作を検証し、続いて埋め込み引用符の回帰ケースを追加して、起動されたプログラムが元の引数を受け取ることを確認してください。

索引モデルが issue の本文から書いたものです。

説明

bug

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. For any argument that contains a double-quote, the output is malformed.

Trace
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); 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.

主要言語
TypeScript
スター
5
フォーク
1
平均マージ
18時間 26分
マージ済み PR(30日)
229

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

diffplug/dormouse のほかの issue

diffplug/dormouse の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。