fix: Round 8 polish — encrypt wipe, update worker leak, CLI, DPR change#77
Closed
nelsonduarte wants to merge 7 commits into
Closed
fix: Round 8 polish — encrypt wipe, update worker leak, CLI, DPR change#77nelsonduarte wants to merge 7 commits into
nelsonduarte wants to merge 7 commits into
Conversation
QLineEdit text for owner/user/decrypt passwords persisted in memory for the entire session. Now cleared via try/finally in _run() to align with the broader wipe_pdf_password() pattern. Addresses R8-H1.
The _update_worker QObject lived for the lifetime of the application because only _update_thread.deleteLater was wired. Now released in _on_update_found() via _release_update_worker() and called defensively from closeEvent. Also removes the dead _update_ready signal: it was declared at the class level and connected to _notify_update, but never emitted — the actual update notification path is via _update_worker.done. Addresses R8-H2 and R8 dead-code finding.
Previously only sys.argv[1] was opened, so multi-file "Open With" or drag-and-drop of N>1 PDFs onto the executable silently dropped every file after the first. -h / --help was treated as an invalid path and the app launched into the welcome screen. Now uses argparse: accepts multiple PDF paths (each opens in its own tab via _load_and_track), and exposes standard --help / --version flags that exit before QApplication is constructed. Addresses R8-M1.
Both viewer/canvas.py and editor/canvas.py read devicePixelRatioF() only inside _schedule_visible(). Without a screenChanged handler, moving the window between 100% and 200% monitors (or changing the DPR of an active monitor via Windows Display Settings) left every visible page blurry until the next zoom interaction. New showEvent override connects to window.windowHandle().screenChanged and invalidates cached pixmaps on DPR change, then re-queues the visible range. The connect is guarded against duplicate handlers on re-show / tab switch. Addresses R8/D1.
PdfReader(wm_path) raised PdfReadError cryptically when the watermark PDF was itself encrypted (rare but observed with corporate stamp PDFs). Now a dedicated _prompt_watermark_password() helper prompts for the watermark's password before pre-flight and the worker decrypts the second reader with it, kept separate from self._pdf_password so source and watermark credentials don't mix. Addresses R8 bonus #6.
A malformed outline (cyclic refs, bad page indexes, unexpected entry shape) could raise mid-build and leave the TOC panel in an inconsistent state — half-populated and surfaced as a stack trace. Now the failure is logged via logging.warning and the TOC tree is reset to an empty / hidden state so the rest of the viewer stays usable. Addresses R8 bonus #7.
10 new tests guard the PR-C wiring against silent regressions: - encrypt._clear_password_fields() + try/finally hookup - _release_update_worker helper + _update_ready signal removal - argparse CLI (multi-PDF, --help, --version) — also exercises the subprocess version/help flags end-to-end - screenChanged DPR handler on viewer + editor canvases - watermark encrypted PDF prompt path - _populate_toc try/except + logging
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes 7 selective findings from audit Round 8: 2 HIGH, 3 MEDIUM, 2 BONUS polish items.
Fixes
app/tools/encrypt.py) —edit_owner/edit_owner_confirm/edit_user/edit_pwdQLineEdits persisted password text for the entire session. New_clear_password_fieldsinvoked from try/finally in_run()wipes them on both success and exception paths.app/window.py) —_update_workerQObject was neverdeleteLater()'d, leaking permanently. New_release_update_workerhelper called from both_on_update_foundandcloseEvent. (Caveat: no-update path only releases atcloseEvent— see commit body for future symmetric cleanup option.)pdfapps.py) — onlysys.argv[1]was opened;-h/--helpsilently ignored; no--version. Now usesargparsewithprog=\"pdfapps\",add_help=True,--versionreturning `PDFApps {APP_VERSION}`, accepts multiple PDF paths vianargs=\"*\", opens each as a tab via existing_load_and_track. Validation requires.pdfextension +os.path.isfile.app/viewer/canvas.py,app/editor/canvas.py) — neither canvas had a handler forQWindow.screenChanged; moving the window between 100%↔200% monitors left pages blurry until next zoom. NewshowEventoverride connects towindow().windowHandle().screenChangedand invalidates cached pixmaps via_genbump +entry.pixmap = None+_schedule_visible()._update_readysignal (app/window.py:271) — declared and connected to_notify_updatebut never emitted (the actual notification path is via_update_worker.done). Removed.Bonus fixes
app/tools/watermark.py) —PdfReader(wm_path)raisedPdfReadErrorcryptically on encrypted watermark PDFs. New_prompt_watermark_passwordhandles it viaprompt_pdf_passwordhelper, distinct fromself._pdf_password(which tracks the source PDF)._populate_tocgraceful failure (app/viewer/panel.py) — malformed TOC could leave the panel in inconsistent state. Now wrapped in try/except +logging.warning; TOC panel hides on failure.Tests
10 new tests in
tests/test_round8_fixes.py:test_encrypt_clears_password_fieldstest_update_worker_release_helper_existstest_update_ready_signal_removedtest_pdfapps_uses_argparsetest_pdfapps_version_flag_runs(subprocess)test_pdfapps_help_flag_runs(subprocess)test_viewer_canvas_handles_screen_changedtest_editor_canvas_handles_screen_changedtest_watermark_prompts_for_encrypted_wmtest_populate_toc_logs_on_failureNote: Qt-bound paths use source-level pattern matching, not functional Qt event-loop testing. The CLI subprocess tests are genuine integration. Behavioural validation of Qt paths requires manual QA.
Final
main), 1 skippedpython pdfapps.py --version→ `PDFApps 1.13.14`python pdfapps.py --help→ usage + flagsOptional follow-ups (not blocking)
_update_workerfrom_update_thread.finishedfor symmetric cleanup on no-update path.