Add a pytest suite covering the pure logic of the DeDRM and Obok plugins.
Because the plugins normally run inside calibre and use intra-package
imports, tests/dedrm_test_utils.py sets up an import shim (plugin dirs on
sys.path, a minimal calibre stub, and a synthetic `dedrm` package) so the
modules can be imported and exercised standalone.
Coverage:
- alfcrypto: PC1 and Topaz cipher round-trips, PBKDF2 vs hashlib.
- kgenpids / kindlepid: PID encoding, bit-field extraction, device-PID
and serial-PID known vectors, CRC32.
- mobidedrm: PC1 round-trip, trailing-data sizing, bad-key handling.
- ineptpdf / ineptepub: nunpack and PKCS7 unpad.
- topazextract: encoded number/string parsing, plus a regression test
that a malicious header tag ("../../evil") cannot escape the output
directory (covers the path-traversal fix).
- obok: unpad, hash-key table, SafeUnbuffered str/bytes handling.
- utilities / argv_utils: uStrCmp normalisation, unicode_argv.
- erdr2pml: deXOR/sanitiseFileName, skipped on Python 3.13+ where the
module's `cgi` import is unavailable.
Run with `poetry install` then `poetry run pytest`. 36 pass, 2 skip on
Python 3.13+.
Note: this surfaced two dead-code modules that are broken on Python 3
(aescbc's pure-Python AES and kgenpids.decode, neither on a live path,
since the real crypto goes through pycryptodome); left as-is here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
792 B
Python
35 lines
792 B
Python
"""Tests for the Obok (Kobo) plugin core."""
|
|
|
|
import io
|
|
|
|
import dedrm_test_utils as U
|
|
|
|
obok = U.load("obok")
|
|
|
|
|
|
def test_unpad_removes_pkcs7_padding():
|
|
assert obok.unpad(b"data\x04\x04\x04\x04") == b"data"
|
|
|
|
|
|
def test_kobo_hash_keys_present():
|
|
assert obok.KOBO_HASH_KEYS == ["88b3a2e13", "XzUhGYdFp", "NoCanLook", "QJhwzAtXL"]
|
|
|
|
|
|
class _FakeStream:
|
|
encoding = "utf-8"
|
|
|
|
def __init__(self):
|
|
self.buffer = io.BytesIO()
|
|
|
|
|
|
def test_safeunbuffered_encodes_str():
|
|
fake = _FakeStream()
|
|
obok.SafeUnbuffered(fake).write("héllo")
|
|
assert fake.buffer.getvalue() == "héllo".encode("utf-8")
|
|
|
|
|
|
def test_safeunbuffered_passes_bytes_through():
|
|
fake = _FakeStream()
|
|
obok.SafeUnbuffered(fake).write(b"\x00\x01\x02")
|
|
assert fake.buffer.getvalue() == b"\x00\x01\x02"
|