Move the copies of unpad, crc32, checksumPid and pidFromSerial that were
scattered across the plugin into utilities.py, and add a shared safe_join
that generalizes the Topaz extraction path-traversal fix.
- unpad: adobekey, ineptepub and ineptpdf import the shared helper. The
four bare-script key tools keep their local copies since they run
without a package context.
- checksumPid is type-preserving (bytes for kgenpids/kindlepid, str for
mobidedrm) so every call site keeps its exact behavior.
- kgenpids falls back to an absolute import because it is imported
top-level by the worker modules.
- topazextract.extractFiles uses safe_join; genbook is unchanged as it
only handles already-sanitized names.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix str/bytes and leftover-py2 defects across the plugin, several on live
decryption paths:
- erdr2pml.py: getText() footnote/sidebar handling mixed a bytes
accumulator with str literals and called ord() on a bytes element,
crashing on eReader/.pdb books that contain footnotes or sidebars.
- ion.py: readdecimal() did `[ord(x) for x in self.read(...)]` over
bytes (ord(int)), crashing KFX decryption on Ion DECIMAL values;
printlob() had the same ord()-over-bytes in its debug path.
- zipfilerugged.py: `isinstance(file, unicode)` raised NameError when a
file-like object (not a path string) was passed to the ZipFile.
- utilities.py: SafeUnbuffered.write referenced the undefined `unicode`
(same fix already applied to the obok copy).
- ineptpdf.py: ord(bookkey[0]) over an int in an error-diagnostic print.
- epubfontdecrypt.py: removed a dead py2 itertools.izip fallback.
- convert2xml.py: escapestr did bytes.replace(str, ...).
- kgenpids.py: decode() built a str result then += bytes.
Cleanups from the earlier shim removal: drop now-unused `import sys`
(alfcrypto, utilities, kgenpids); unicode_argv returns list(sys.argv) so
callers can't mutate the process-global sys.argv.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The plugins target calibre 5/6 (Python 3) and the Poetry environment
pins Python >=3.8, so the Python 2 fallbacks are dead code. This removes
them throughout both plugins (behaviour on Python 3 is unchanged):
- Drop all `from __future__` imports.
- Collapse `if sys.version_info[0] == 2: ... else: ...` blocks to their
Python 3 branch (ineptpdf, mobidedrm, kindlekey, kgenpids, alfcrypto,
erdr2pml, ineptepub, obok, and the various unpad() helpers, etc.).
- Replace `_winreg` import fallbacks with plain `import winreg`, and
delete the py2-only adobekey_winreg_unicode module (now unreferenced).
- Drop py2 name shims: `unicode`/`unichr`, `.iteritems()`,
`from StringIO import StringIO`, `htmlentitydefs` fallback, and the
Windows CommandLineToArgvW dance in unicode_argv (py3 sys.argv is
already Unicode on every platform).
- Remove the "Calibre < 5" (py2) bugfix block from the compat header.
Verified: every .py file in both plugins still byte-compiles.
Scope: the maintained DeDRM_plugin and Obok_plugin only. The archival
standalone scripts under Other_Tools/ are left as historical snapshots.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In order to properly get pids etc. we need to pass bytes to MD5 and SHA1
instead of unicode strings. Also ord() is no longer needed since
data is bytes value gets int and we need chr() to get characters from
the mapping bytearrays.
THIS IS ON THE MASTER BRANCH. The Master branch will be Python 3.0 from now on. While Python 2.7 support will not be deliberately broken, all efforts should now focus on Python 3.0 compatibility.
I can see a lot of work has been done. There's more to do. I've bumped the version number of everything I came across to the next major number for Python 3.0 compatibility indication.
Thanks everyone. I hope to update here at least once a week until we have a stable 7.0 release for calibre 5.0