Skip to content

fix(windows): preserve YaXUnit /C launch argument - #45

Merged
alkoleft merged 1 commit into
alkoleft:masterfrom
Agrajaga:codex/fix-windows-c-raw-arg
Jul 23, 2026
Merged

fix(windows): preserve YaXUnit /C launch argument#45
alkoleft merged 1 commit into
alkoleft:masterfrom
Agrajaga:codex/fix-windows-c-raw-arg

Conversation

@Agrajaga

@Agrajaga Agrajaga commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • pass the generated /C"RunUnitTests=..." parameter through a guarded Windows raw command-line argument for 1cv8 and 1cv8c;
  • retain standard Rust argument escaping for other executables and reject embedded quotes or line breaks in the raw payload;
  • mask separated, compact and connection-string password forms in debug-rendered commands;
  • avoid logging values from additional Enterprise launch keys;
  • keep Unix-only syntax-test helpers gated so the Windows regression suite compiles.

Root cause

std::process::Command::arg escapes the quotes embedded in the complete 1C /C parameter. The resulting Windows command line contains /C\"RunUnitTests=...\", which the 1C parser ignores, so Enterprise starts in normal mode instead of starting YaXUnit.

Impact

YaXUnit launches on Windows now receive the literal command-line form expected by 1C:

/C"RunUnitTests=..."

Password values are also removed from process debug output.

Validation

  • 4 command-rendering/password-redaction tests pass.
  • 3 Windows tests for raw YaXUnit arguments, normal non-1C escaping and payload validation pass.
  • cargo check --all-targets passes.
  • cargo fmt --all -- --check passes.
  • git diff --check passes.
  • Independent reviewer and Rust-focused review found no remaining issues.

A live YaXUnit information-base run was not performed because this checkout does not contain a configured test information base.

Fixes #44

Summary by CodeRabbit

  • Исправления

    • Уточнена обработка ключей запуска /C, /execute и /out, включая варианты с разными префиксами, пробелами и разделителями.
    • Исправлено формирование аргументов для запуска MCP: /C и значение payload теперь передаются раздельно.
    • Некорректные присоединённые алиасы, например /C"RunUnitTests", корректно отклоняются до запуска клиента.
  • Документация

    • Обновлены инструкции по запуску MCP и описания параметров конфигурации с актуальным форматом payload.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Обновлена обработка зарезервированных ключей запуска и формат передачи /C: ключ и payload теперь являются отдельными аргументами process argv. Добавлены проверки алиасов, обновлены тесты и документация.

Changes

Обработка аргументов запуска

Layer / File(s) Summary
Сопоставление алиасов ключей
src/domain/runner.rs
Добавлен общий matcher алиасов с проверкой префиксов, регистра, пробелов и границ совпадения; добавлены unit-тесты.
Формирование payload /C
src/platform/enterprise.rs, src/cli/args.rs, docs/..., SKILL/references/project-workflows.md, src/config/model.rs
/C и payload передаются отдельными аргументами, фильтрация зарезервированных ключей использует matcher, а документация описывает новый формат.
Проверка raw-ключей перед запуском
src/cli/execute.rs, src/use_cases/launch_app.rs, tests/cli_launch.rs
Проверки CLI и use case распознают варианты /C, /Execute и /Out; тест подтверждает отказ до запуска процесса.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • alkoleft/v8-runner-rust#34: Использует распознавание тех же зарезервированных raw-ключей в проверках wait-режима.

Suggested reviewers: alkoleft

Poem

Я, кролик, /C разделил,
Алиасы ловко проверил.
Payload отдельно поскакал,
Тесты следы его искали.
Документация морковкой хрустит —
Запуск теперь яснее звучит!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title matches the main fix: Windows YaXUnit /C argument handling.
Linked Issues check ✅ Passed Changes appear to satisfy #44 by preserving raw YaXUnit /C on Windows, keeping normal escaping elsewhere, and masking passwords in debug output.
Out of Scope Changes check ✅ Passed No clear out-of-scope code changes; docs, tests, and helper refactors all support the Windows launch and redaction fixes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Agrajaga
Agrajaga marked this pull request as ready for review July 23, 2026 09:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/use_cases/run_tests/helpers.rs`:
- Around line 347-350: Обновите логирование вокруг
effective_enterprise_launch_keys: сначала получите фактически используемый
список additional_launch_keys, затем передайте его длину в сообщение о resolved
ключах вместо значения из config.tools.enterprise.additional_launch_keys.
Сохраните передачу этого же списка в EnterpriseDsl.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a448c000-0555-4375-9b29-0752ebf9aa1c

📥 Commits

Reviewing files that changed from the base of the PR and between be558db and e6a210e.

📒 Files selected for processing (3)
  • src/platform/process.rs
  • src/use_cases/check_syntax.rs
  • src/use_cases/run_tests/helpers.rs

Comment thread src/use_cases/run_tests/helpers.rs Outdated

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- pass managed /C payload as a separate argv value

- share reserved launch key alias matching across CLI paths

- update launch/test docs and regression coverage
@alkoleft
alkoleft force-pushed the codex/fix-windows-c-raw-arg branch from 62ed707 to 45f38df Compare July 23, 2026 15:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/cli/execute.rs (1)

1469-1473: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Вынести общий список зарезервированных ключей /C//Execute//Out в domain/runner.rs.

is_reserved_raw_launch_key и is_wait_reserved_raw_key дублируют один и тот же массив ["c", "execute", "out"] и одну и ту же проверку через launch_key_alias_matches. Стоит добавить единую функцию (например, pub(crate) fn is_typed_option_alias(raw: &str) -> bool) в src/domain/runner.rs рядом с launch_key_alias_matches и использовать её в обоих местах — это устранит риск расхождения списков при будущих изменениях.

  • src/cli/execute.rs#L1469-L1473: заменить тело is_reserved_raw_launch_key на вызов нового общего хелпера из crate::domain::runner.
  • src/use_cases/launch_app.rs#L269-L273: заменить тело is_wait_reserved_raw_key на вызов того же общего хелпера.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/execute.rs` around lines 1469 - 1473, Вынеси общий список и проверку
зарезервированных алиасов в новую функцию `is_typed_option_alias` рядом с
`launch_key_alias_matches` в `src/domain/runner.rs`; затем в
`src/cli/execute.rs#L1469-L1473` замени тело `is_reserved_raw_launch_key`
вызовом этого хелпера, а в `src/use_cases/launch_app.rs#L269-L273` аналогично
обнови `is_wait_reserved_raw_key`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/platform/enterprise.rs`:
- Around line 159-162: Update the Windows launch flow between build_launch_args
and process.rs so the /C switch and its payload are passed as one raw argument
in the form /C"payload", rather than separate args entries. Use Windows
CommandExt::raw_arg, reject payloads containing embedded quotes or newline
characters, and preserve the existing argument behavior for other launch
options.

---

Nitpick comments:
In `@src/cli/execute.rs`:
- Around line 1469-1473: Вынеси общий список и проверку зарезервированных
алиасов в новую функцию `is_typed_option_alias` рядом с
`launch_key_alias_matches` в `src/domain/runner.rs`; затем в
`src/cli/execute.rs#L1469-L1473` замени тело `is_reserved_raw_launch_key`
вызовом этого хелпера, а в `src/use_cases/launch_app.rs#L269-L273` аналогично
обнови `is_wait_reserved_raw_key`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2d3bac15-6d9d-4e35-9a7b-b09dba611ced

📥 Commits

Reviewing files that changed from the base of the PR and between 62ed707 and 45f38df.

📒 Files selected for processing (10)
  • SKILL/references/project-workflows.md
  • docs/CAPABILITIES.md
  • docs/CONFIGURATION.md
  • src/cli/args.rs
  • src/cli/execute.rs
  • src/config/model.rs
  • src/domain/runner.rs
  • src/platform/enterprise.rs
  • src/use_cases/launch_app.rs
  • tests/cli_launch.rs

Comment on lines 159 to 162
if let Some(c) = &launch.c {
args.push(quoted_c_arg(c));
args.push("/C".to_owned());
args.push(c.clone());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n "raw_arg" --type=rust
rg -n "force_quotes|CommandExt" --type=rust
rg -n "1cv8" src/platform/process.rs -A3 -B3 2>/dev/null
fd -e rs . src/platform | xargs -I{} rg -n "raw_arg|CommandExt" {}

Repository: alkoleft/v8-runner-rust

Length of output: 230


🏁 Script executed:

#!/bin/bash
set -eu

echo "== relevant files =="
git ls-files 'src/platform/*.rs' | sort

echo "== enterprise outline =="
ast-grep outline src/platform/enterprise.rs || true

echo "== process outline =="
ast-grep outline src/platform/process.rs || true

echo "== lines in enterprise.rs around launch args =="
sed -n '1,230p' src/platform/enterprise.rs | cat -n

echo "== process.rs first 220 =="
sed -n '1,220p' src/platform/process.rs | cat -n

echo "== search process launching =="
rg -n "Command|args\\(|spawn|exec|ProcessRunner|process" src/platform -S

Repository: alkoleft/v8-runner-rust

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -eu

echo "== related docs/comments about raw args / Windows cmd.exe =="
rg -n "`#44`|raw|1cv8|1cv8c|C\\\"|RunUnitTests|ProcessRunner|windows|windows-msvc|raw_arg|force_quotes|quoted_c_arg" . -S \
  -g '!target/**' -g '!dist/**' -g '!build/**' -g '!node_modules/**' || true

Repository: alkoleft/v8-runner-rust

Length of output: 50380


🌐 Web query:

Rust std::process::Command on Windows command line escaping args() quote arguments documentation

💡 Result:

On Windows, Rust's std::process::Command handles arguments differently than on Unix because the Windows API (CreateProcessW) accepts a single command-line string rather than an array [1][2]. Rust is responsible for serializing the arguments passed via.arg or.args into this single string, which the child process then parses [1][3]. Key points regarding argument escaping and quoting on Windows include: Standard Behavior: For most applications that follow standard C run-time argument parsing rules, Rust's default escaping logic is safe and sufficient [1][3]. Arguments are passed literally, meaning shell-specific features like glob patterns, variable expansion, or pipe operators are not interpreted [4][2]. Batch File Caveat: A critical exception exists for.bat and.cmd files [1][3]. Because these are executed via cmd.exe, they utilize non-standard, complex argument parsing rules [1][4]. Rust attempts to escape these arguments automatically, but due to the inherent complexity of cmd.exe, it is not always possible to safely escape every input [1][3]. In scenarios where Rust cannot safely escape an argument for a batch file, it will return an InvalidInput error at runtime when attempting to spawn the process [1][3]. Raw Arguments: If you are interacting with tools that use non-standard parsing or if you need to manually control the command line, you can use the CommandExt::raw_arg method [5][3]. This method appends text to the command line without Rust's automatic quoting or escaping [5][6]. This should be used with extreme caution as it bypasses safety mechanisms and can expose your application to command injection vulnerabilities [1][5]. Security Warning: When dealing with untrusted input, particularly when invoking cmd.exe or batch files, exercise significant caution [1][2]. Maliciously crafted arguments can potentially lead to arbitrary shell command execution [1][3]. Where possible, validate input to a safe, known-good subset (such as alphanumeric characters) before passing it to Command [1][5]. For complex command lines involving batch files, consider writing the arguments to a temporary batch file and executing that file instead of building a complex, dynamic command string [5][7].

Citations:


🌐 Web query:

Rust std::process::Command.raw_arg appends with space documentation

💡 Result:

The raw_arg method in Rust’s std::os::windows::process::CommandExt trait does not automatically append a space [1][2]. It appends the provided literal text to the command line without performing any quoting or escaping [3][1]. Because raw_arg treats the input as raw text to be added directly to the command line string [4], the responsibility for formatting—including adding necessary spaces between arguments—lies entirely with the caller [1][2]. This method is specifically intended for scenarios where you need to manually construct the command line for applications that do not follow standard argument parsing rules (such as cmd.exe) [1][4]. When using raw_arg, you must handle the assembly of the command line string manually, ensuring that spaces are included where appropriate to separate distinct arguments [1][2]. It is highly recommended to use this method with caution, as it bypasses the standard library's automatic escaping and can introduce security vulnerabilities if used with untrusted inputs [4][5][6].

Citations:


Не разделять /C и payload на два Vec<String> при запуске на Windows.

build_launch_args кладёт в args "/C" и затем c.clone() как разные элементы, а process.rs передаёт их через стандартный запуск, где нет Windows-специфичного raw_arg. На Windows такой Command::args(...) не склеит их слитно и payload с пробелами/кавычками попадёт под стандартное экранирование/кавычки, поэтому для 1cv8/1cv8c нужно собирать слитную форму /C"payload" через CommandExt::raw_arg в src/platform/process.rs с отказом при встроенных кавычках и переводах строк.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/platform/enterprise.rs` around lines 159 - 162, Update the Windows launch
flow between build_launch_args and process.rs so the /C switch and its payload
are passed as one raw argument in the form /C"payload", rather than separate
args entries. Use Windows CommandExt::raw_arg, reject payloads containing
embedded quotes or newline characters, and preserve the existing argument
behavior for other launch options.

@alkoleft
alkoleft merged commit 72d346c into alkoleft:master Jul 23, 2026
1 check passed
@alkoleft

Copy link
Copy Markdown
Owner

@Agrajaga PR был переработан, проверь пожалуйста под windows

@Agrajaga

Copy link
Copy Markdown
Contributor Author

@alkoleft Проверил переработанный вариант под Windows на merged master 72d346c0 (head PR 45f38dfd), платформа 1С 8.3.27.2130.

Реальный запуск через v8-runner launch thin --c RunUnitTests=<config> успешен: YaXUnit распознал /C, запустил модуль ТестZybio, результат JUnit — 1 тест, 0 failures, 0 errors. Runner-log завершился сообщением о завершении YAxUnit, после чего процессы 1С закрылись.

Итого: передача /C и payload отдельными argv на проверенной Windows/1С работает; замечание о необходимости обязательного raw_arg экспериментом не подтвердилось.

Дополнительно: cargo check --bin v8-runner на Windows проходит. Целевой cargo test platform::enterprise сейчас не стартует из-за отдельной Windows-совместимости тестового кода: без cfg(unix) импортирован std::os::unix::fs::PermissionsExt в src/use_cases/check_syntax.rs и вызывается set_mode.

@Agrajaga
Agrajaga deleted the codex/fix-windows-c-raw-arg branch July 24, 2026 07:00
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.

Windows: YaXUnit /C argument is escaped and ignored by 1C

2 participants