fix(client): harden CLI args, log escaping, and local artifact opens
- parse_ull_arg() rejects a leading '-'/'+' (strtoull would silently wrap -1 to ULLONG_MAX) and --chunk-size/--delta-max enforce their upper bounds. - Escape local untrusted paths before logging (client_send, scanner, --filter rule, pattern-file reads) with output_escape(..., 8-bit mode). - Read --exclude-from/--include-from through the bounded line reader. - Open --log-file with O_NOFOLLOW|O_CLOEXEC, mode 0600, via open+fdopen; create --write-batch with O_NOFOLLOW|O_CLOEXEC, mode 0600. - Reject --dry-run together with --write-batch (dry-run must not write the batch file), alongside the existing --read-batch/--only-write-batch rules. Tests: signed/oversized numeric rejection, over-long pattern file, dry-run + write-batch unit and integration coverage.
This commit is contained in:
@@ -117,4 +117,16 @@ def test_batch_modes_conflict():
|
||||
cmd = _run(["--source-dir", SOURCE_DIR, "--dest-dir", DEST1] + flags)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
|
||||
assert result.returncode != 0, \
|
||||
f"expected conflict failure for {flags}: {result.stderr}"
|
||||
f"expected conflict failure for {flags}: {result.stderr}"
|
||||
|
||||
|
||||
@pytest.mark.ci
|
||||
def test_dry_run_rejects_write_batch():
|
||||
"""--dry-run must not emit a batch file (it must not mutate anything)."""
|
||||
if os.path.exists(BATCH_FILE):
|
||||
os.unlink(BATCH_FILE)
|
||||
cmd = _run(["--source-dir", SOURCE_DIR, "--dest-dir", DEST1,
|
||||
"--dry-run", "--write-batch", BATCH_FILE])
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
|
||||
assert result.returncode != 0, result.stderr
|
||||
assert not os.path.exists(BATCH_FILE), "dry-run must not create a batch file"
|
||||
Reference in New Issue
Block a user