Modernizes the DeDRM and Obok plugins: fixes a security bug, replaces the abandoned crypto dependency and manages the environment with Poetry, removes the Python 2 compatibility layer, deduplicates copy-pasted helpers, and adds a pytest suite plus CI.
Security
Fix an arbitrary-file-write (path traversal / zip-slip) in Topaz extraction, where an untrusted book-record name like ../../evil could write outside the output directory. Generalized into a shared safe_join helper.
Dependencies
Manage the dev/standalone environment with Poetry (package-mode = false).
Drop the abandoned pycrypto (unmaintained since 2014, CVE-2013-7459) in favor of the maintained pycryptodomex (Cryptodome namespace) already preferred by the code.
Declare lxml, an optional apsw group for Nook, and legacy-cgi (only on Python 3.13+, where the stdlib cgi module was removed and erdr2pml still needs it).
Python 3 modernization
Remove the Python 2 compatibility shims throughout both plugins (version_info branches, __future__ imports, _winreg, unicode/xrange/iteritems, etc.).
Fix invalid string escape sequences and several real Python 3 correctness bugs found in review (bytes/ord mistakes in erdr2pml footnotes, ion KFX decimal reads, a zipfilerugged NameError).
Delete the dead pure-Python AES (aescbc.py) and its unused wrapper; the live crypto path is Cryptodome.
Refactor
Move the copies of unpad, crc32, checksumPid and pidFromSerial that were duplicated across many files into utilities.py. checksumPid is type-preserving so every call site keeps its exact behavior.
Tests & CI
Add a pytest suite for both plugins (51 tests) with a synthetic-package loader so the modules import outside calibre.
Add ci.yml running the suite on PRs to master across Python 3.9 / 3.11 / 3.13.
Modernize the packaging workflow (renamed main.yml -> release.yml) and pin all actions to commit SHAs.
## Summary
Modernizes the DeDRM and Obok plugins: fixes a security bug, replaces the abandoned crypto dependency and manages the environment with Poetry, removes the Python 2 compatibility layer, deduplicates copy-pasted helpers, and adds a pytest suite plus CI.
## Security
- Fix an arbitrary-file-write (path traversal / zip-slip) in Topaz extraction, where an untrusted book-record name like `../../evil` could write outside the output directory. Generalized into a shared `safe_join` helper.
## Dependencies
- Manage the dev/standalone environment with Poetry (`package-mode = false`).
- Drop the abandoned `pycrypto` (unmaintained since 2014, CVE-2013-7459) in favor of the maintained `pycryptodomex` (`Cryptodome` namespace) already preferred by the code.
- Declare `lxml`, an optional `apsw` group for Nook, and `legacy-cgi` (only on Python 3.13+, where the stdlib `cgi` module was removed and `erdr2pml` still needs it).
## Python 3 modernization
- Remove the Python 2 compatibility shims throughout both plugins (version_info branches, `__future__` imports, `_winreg`, `unicode`/`xrange`/`iteritems`, etc.).
- Fix invalid string escape sequences and several real Python 3 correctness bugs found in review (bytes/`ord` mistakes in erdr2pml footnotes, ion KFX decimal reads, a zipfilerugged `NameError`).
- Delete the dead pure-Python AES (`aescbc.py`) and its unused wrapper; the live crypto path is Cryptodome.
## Refactor
- Move the copies of `unpad`, `crc32`, `checksumPid` and `pidFromSerial` that were duplicated across many files into `utilities.py`. `checksumPid` is type-preserving so every call site keeps its exact behavior.
## Tests & CI
- Add a pytest suite for both plugins (51 tests) with a synthetic-package loader so the modules import outside calibre.
- Add `ci.yml` running the suite on PRs to master across Python 3.9 / 3.11 / 3.13.
- Modernize the packaging workflow (renamed `main.yml` -> `release.yml`) and pin all actions to commit SHAs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Modernizes the DeDRM and Obok plugins: fixes a security bug, replaces the abandoned crypto dependency and manages the environment with Poetry, removes the Python 2 compatibility layer, deduplicates copy-pasted helpers, and adds a pytest suite plus CI.
Security
../../evilcould write outside the output directory. Generalized into a sharedsafe_joinhelper.Dependencies
package-mode = false).pycrypto(unmaintained since 2014, CVE-2013-7459) in favor of the maintainedpycryptodomex(Cryptodomenamespace) already preferred by the code.lxml, an optionalapswgroup for Nook, andlegacy-cgi(only on Python 3.13+, where the stdlibcgimodule was removed anderdr2pmlstill needs it).Python 3 modernization
__future__imports,_winreg,unicode/xrange/iteritems, etc.).ordmistakes in erdr2pml footnotes, ion KFX decimal reads, a zipfileruggedNameError).aescbc.py) and its unused wrapper; the live crypto path is Cryptodome.Refactor
unpad,crc32,checksumPidandpidFromSerialthat were duplicated across many files intoutilities.py.checksumPidis type-preserving so every call site keeps its exact behavior.Tests & CI
ci.ymlrunning the suite on PRs to master across Python 3.9 / 3.11 / 3.13.main.yml->release.yml) and pin all actions to commit SHAs.🤖 Generated with Claude Code