diffplug / diffplug/dormouse

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

Abierto
#162 1 comentario 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
5
Forks
0
Merge medio
14 h 13 min
PR fusionados (30 d)
199

Descripción

## `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._

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Comience en dor/src/commands/shell-quote.ts, en quoteCmdArg, y revise las expectativas existentes en dor/test/cli-output.test.mjs alrededor de las líneas 204-206. Valide el comportamiento elegido para las comillas literales en un host Windows cmd.exe, después añada un caso de regresión con comillas incrustadas y confirme que el programa iniciado recibe el argumento original.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
cli
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.