diff --git a/CHANGELOG.md b/CHANGELOG.md index d853229..76efb4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.4.1 - 2026-08-26 + +- 测试锁定 `py.typed` 仍随包装分发,并增加 `compileall` 语法检查 +- 增加 Windows 盘符路径清洗测试,避免 `C:\...` 被当成可逃逸根路径 + ## 0.4.0 - 2026-08-13 - **二次乱码修复**:乱码文件被重新打包成"正常"压缩包(文件名带 diff --git a/pyproject.toml b/pyproject.toml index 9d877c8..8554890 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "luanma" -version = "0.4.0" +version = "0.4.1" description = "Fix mojibake filenames in zip archives and extracted folders: auto-detect GBK/Big5/Shift-JIS/EUC-KR, preview, safely extract, rewrite to UTF-8, or rename on disk | 压缩包与目录乱码文件名自动检测、修复与安全解压工具" readme = "README.md" requires-python = ">=3.9" diff --git a/src/luanma/__init__.py b/src/luanma/__init__.py index c96b4e4..0e8f557 100644 --- a/src/luanma/__init__.py +++ b/src/luanma/__init__.py @@ -16,7 +16,7 @@ preview_zip, ) -__version__ = "0.4.0" +__version__ = "0.4.1" __all__ = [ "ArchiveError", diff --git a/tests/test_compileall.py b/tests/test_compileall.py new file mode 100644 index 0000000..5c06269 --- /dev/null +++ b/tests/test_compileall.py @@ -0,0 +1,12 @@ +"""CI already runs pytest; this keeps a syntax check without editing workflows.""" +from __future__ import annotations + +import compileall +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +def test_sources_and_tests_compile() -> None: + assert compileall.compile_dir(str(ROOT / "src"), quiet=1, force=True) + assert compileall.compile_dir(str(ROOT / "tests"), quiet=1, force=True) diff --git a/tests/test_sanitize.py b/tests/test_sanitize.py index 890799a..d8a8482 100644 --- a/tests/test_sanitize.py +++ b/tests/test_sanitize.py @@ -46,3 +46,19 @@ def test_junk_macosx(): def test_junk_normal_files_pass(): assert not is_junk(["dir", "报告.docx"]) assert not is_junk(["DS_Store提醒.txt"]) + + +def test_windows_drive_letter_cannot_escape(): + parts, changed = safe_components(r"C:\Windows\system32\evil.dll") + assert changed + assert parts[0] != "C:" + assert all(":" not in part for part in parts) + assert parts[-1] == "evil.dll" + + +def test_py_typed_marker_is_shipped(): + from pathlib import Path + + import luanma + + assert (Path(luanma.__file__).resolve().parent / "py.typed").is_file()