From 7a1babb17521fe657b8759534242e0109467ca2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=98=E9=9B=85=E3=81=AE=E5=92=B8=E9=B1=BC?= <3129538298@qq.com> Date: Wed, 26 Aug 2026 16:57:37 +0800 Subject: [PATCH 1/2] Reject negative --top instead of printing zero scan findings. --- src/longpath/validate.py | 7 +++++++ tests/test_negative_top.py | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/longpath/validate.py create mode 100644 tests/test_negative_top.py diff --git a/src/longpath/validate.py b/src/longpath/validate.py new file mode 100644 index 0000000..8796fe0 --- /dev/null +++ b/src/longpath/validate.py @@ -0,0 +1,7 @@ +"""Small CLI argument guards.""" + + +def require_nonneg_top(n: int) -> int: + if int(n) < 0: + raise ValueError("--top must be >= 0") + return int(n) diff --git a/tests/test_negative_top.py b/tests/test_negative_top.py new file mode 100644 index 0000000..385e52b --- /dev/null +++ b/tests/test_negative_top.py @@ -0,0 +1,10 @@ +import pytest + +from longpath.validate import require_nonneg_top + + +def test_require_nonneg_top(): + assert require_nonneg_top(0) == 0 + assert require_nonneg_top(20) == 20 + with pytest.raises(ValueError, match="--top"): + require_nonneg_top(-1) From 42c0ae7a8451d3b40961c09f562b78abcd3ad540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=98=E9=9B=85=E3=81=AE=E5=92=B8=E9=B1=BC?= <3129538298@qq.com> Date: Wed, 26 Aug 2026 17:24:53 +0800 Subject: [PATCH 2/2] Reject negative --top in scan CLI. --- src/longpath/cli.py | 7 +++++-- tests/test_negative_top.py | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/longpath/cli.py b/src/longpath/cli.py index 6229fb5..73e587e 100644 --- a/src/longpath/cli.py +++ b/src/longpath/cli.py @@ -233,7 +233,7 @@ def _policy_lines(pal: Palette) -> List[str]: def _clean_base(base: Optional[str]) -> Optional[str]: - # `--base "C:\dest\"` in PowerShell/cmd turns the trailing \" into a + # `--base "C:\\dest\\"` in PowerShell/cmd turns the trailing \\" into a # literal quote; a path cannot legally end in one, so strip it. if base is None: return None @@ -247,6 +247,9 @@ def _run_scan(args: argparse.Namespace) -> int: if args.limit < 16: _err("longpath: --limit must be at least 16") return EXIT_ERROR + if args.top < 0: + _err("longpath: --top must be >= 0") + return EXIT_ERROR base = _clean_base(args.base) result = scan_tree(args.dir, limit=args.limit, base=base, exclude=args.exclude) @@ -472,7 +475,7 @@ def main(argv: Optional[List[str]] = None) -> int: except (AttributeError, OSError): pass - # sugar: `longpath D:\dir` == `longpath scan D:\dir`; bare `longpath` scans . + # sugar: `longpath D:\\dir` == `longpath scan D:\\dir`; bare `longpath` scans . if not argv: argv = ["scan"] elif argv[0] not in _SUBCOMMANDS and not argv[0].startswith("-"): diff --git a/tests/test_negative_top.py b/tests/test_negative_top.py index 385e52b..29770f1 100644 --- a/tests/test_negative_top.py +++ b/tests/test_negative_top.py @@ -2,9 +2,17 @@ from longpath.validate import require_nonneg_top +from conftest import run_cli + def test_require_nonneg_top(): assert require_nonneg_top(0) == 0 assert require_nonneg_top(20) == 20 with pytest.raises(ValueError, match="--top"): require_nonneg_top(-1) + + +def test_scan_negative_top_exit_2(tree): + p = run_cli("scan", str(tree), "--top", "-1") + assert p.returncode == 2 + assert "--top must be >= 0" in p.stderr