Strengthen weak-assertion / false-confidence tests:
- test_alfcrypto: replace the tautological ctx_init determinism check
with an independent golden vector, and add a golden Topaz decrypt
vector that does not rely on the test's own inverse helper (so a
systematic cipher bug is caught, not just round-trip symmetry). Pin
the PC1 bad-key assertion to match="Bad key length", and load
alfcrypto via the dedrm package so the test exercises the same module
object that topazextract/mobidedrm import.
- test_mobidedrm: pin the PC1 bad-key assertion to the guard message.
- test_topazextract: make the path-traversal regression rely on the
depth-independent positive oracle (the sanitised file must land inside
outdir, which fails against the pre-fix code) plus an exact-contents
check, instead of brittle parent-path negatives.
- test_erdr2pml: narrow the import skip to only the missing-cgi case so
a genuinely broken module fails loudly instead of silently skipping.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
"""Tests for erdr2pml (eReader) helpers.
|
|
|
|
erdr2pml imports the stdlib ``cgi`` module, which was removed in Python 3.13.
|
|
The ``legacy-cgi`` backport is a dev dependency so the module imports on modern
|
|
interpreters; the skip guard below keeps the suite green if it is ever run
|
|
without that backport (e.g. a bare Python 3.13+ with no dev extras).
|
|
"""
|
|
|
|
import pytest
|
|
|
|
import dedrm_test_utils as U
|
|
|
|
try:
|
|
erdr2pml = U.load("erdr2pml", package="dedrm")
|
|
_skip_reason = None
|
|
except ImportError as exc: # pragma: no cover - depends on interpreter / deps
|
|
# Only tolerate the specific "no cgi backport" case (Python 3.13+ without
|
|
# legacy-cgi). Any other import error means the module is genuinely broken
|
|
# and must fail loudly rather than silently skip.
|
|
if getattr(exc, "name", None) == "cgi":
|
|
erdr2pml = None
|
|
_skip_reason = "erdr2pml needs the 'cgi' module (install legacy-cgi on Python 3.13+)"
|
|
else:
|
|
raise
|
|
|
|
pytestmark = pytest.mark.skipif(erdr2pml is None, reason=_skip_reason or "")
|
|
|
|
|
|
def test_dexor_is_involutive():
|
|
table = bytes(range(7, 7 + 16))
|
|
text = b"some secret payload!"
|
|
once = erdr2pml.deXOR(text, 0, table)
|
|
assert once != text
|
|
assert erdr2pml.deXOR(once, 0, table) == text
|
|
|
|
|
|
def test_fix_key_known_vector():
|
|
assert erdr2pml.fixKey(bytes([0, 1, 2, 3, 255, 128, 64])) == bytes(
|
|
[0x80, 0x01, 0x02, 0x83, 0x7F, 0x80, 0x40]
|
|
)
|
|
|
|
|
|
def test_fix_key_preserves_length():
|
|
assert len(erdr2pml.fixKey(b"\x00" * 16)) == 16
|
|
|
|
|
|
def test_clean_pml_escapes_high_ascii():
|
|
# bytes 128..255 become \aNNN PML codes; bytes < 128 are left untouched.
|
|
assert erdr2pml.cleanPML(b"abc\x80\xff\x7f") == b"abc\\a128\\a255\x7f"
|
|
|
|
|
|
def test_sanitize_filename_replaces_separators():
|
|
assert erdr2pml.sanitizeFileName("a/b\\c|d") == "a_b_c_d"
|
|
|
|
|
|
def test_sanitize_filename_removes_colon():
|
|
assert ":" not in erdr2pml.sanitizeFileName("foo: bar")
|
|
|
|
|
|
def test_sanitize_filename_strips_control_chars_and_dots():
|
|
assert erdr2pml.sanitizeFileName("...\x01na\tme.") == "name"
|
|
|
|
|
|
def test_sanitize_filename_replaces_angle_brackets():
|
|
assert erdr2pml.sanitizeFileName("<tag>") == "[tag]"
|