Skip to content

feat: add benchmarking suite, hardware AES research, and OS context menu docs#51

Open
ambicuity wants to merge 1 commit intoSUPAIDEAS:mainfrom
ambicuity:feat/research-benchmarking-context-menu
Open

feat: add benchmarking suite, hardware AES research, and OS context menu docs#51
ambicuity wants to merge 1 commit intoSUPAIDEAS:mainfrom
ambicuity:feat/research-benchmarking-context-menu

Conversation

@ambicuity
Copy link
Copy Markdown
Contributor

@ambicuity ambicuity commented Feb 21, 2026

Summary

Closes #47 — Benchmarking suite
Closes #43 — Hardware-accelerated AES research
Closes #46 — OS context menu integration guide

Changes

Benchmarking (#47)

  • docs/BENCHMARKS.md — methodology, results table (passifypdf vs qpdf vs pdftk), and hyperfine usage instructions
  • tests/benchmarks/bench_encrypt.py — reusable Python benchmark script measuring median wall-clock time over 10 iterations; gracefully skips tools not installed on PATH

Hardware AES (#43)

  • docs/HARDWARE_AES_RESEARCH.md — research showing pypdf already leverages hardware AES-NI via the cryptography/OpenSSL backend; recommends exposing passifypdf[fast] as an optional dependency

OS Context Menus (#46)

  • docs/OS_CONTEXT_MENU.md — step-by-step integration guides for macOS (Automator Quick Action), Windows (Send To + Registry), Linux Nautilus, and KDE Dolphin

Testing

All 4 existing tests pass. The benchmark script can be run manually with uv run python tests/benchmarks/bench_encrypt.py.

…cs (closes SUPAIDEAS#43, closes SUPAIDEAS#46, closes SUPAIDEAS#47)

- docs: add docs/BENCHMARKS.md with benchmark methodology, results
  table (passifypdf vs qpdf vs pdftk), and hyperfine usage (closes SUPAIDEAS#47)
- feat: add tests/benchmarks/bench_encrypt.py — a reusable benchmarking
  script that measures median wall-clock time for each tool over 10
  iterations, gracefully skipping tools not installed on PATH (closes SUPAIDEAS#47)
- docs: add docs/HARDWARE_AES_RESEARCH.md — research showing pypdf
  already uses hardware AES-NI via the cryptography/OpenSSL backend;
  recommends exposing 'passifypdf[fast]' optional dependency (closes SUPAIDEAS#43)
- docs: add docs/OS_CONTEXT_MENU.md — step-by-step instructions for
  integrating passifypdf into right-click context menus on macOS
  (Automator Quick Action), Windows (Send To + registry), Linux Nautilus,
  and KDE Dolphin (closes SUPAIDEAS#46)
Copilot AI review requested due to automatic review settings February 21, 2026 02:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a benchmarking suite to compare passifypdf's encryption performance against other CLI tools (qpdf and pdftk), along with research documentation on hardware-accelerated AES encryption and OS-specific context menu integration guides. The PR addresses issue #47 which requested performance comparison benchmarks.

Changes:

  • Added benchmark script to measure and compare encryption speeds across tools
  • Added documentation on hardware AES acceleration research and recommendations
  • Added OS-specific integration guides for macOS, Windows, and Linux context menus

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 22 comments.

Show a summary per file
File Description
uv.lock New dependency lock file with Python version specification
tests/benchmarks/bench_encrypt.py Benchmark script comparing passifypdf, qpdf, and pdftk encryption speeds
tests/benchmarks/init.py Empty module initialization file for benchmarks package
docs/BENCHMARKS.md Documentation of benchmark methodology, results, and usage instructions
docs/HARDWARE_AES_RESEARCH.md Research notes on hardware-accelerated AES encryption via cryptography library
docs/OS_CONTEXT_MENU.md Integration guides for adding passifypdf to OS context menus

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return _median(times)


def benchmark_pdftk(input_path: Path, output_dir: Path) -> float | None:
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint syntax "float | None" requires Python 3.10+, but pyproject.toml specifies "python = ^3.8". Either change the type hints to use "Optional[float]" from typing module, or update the minimum Python version requirement in pyproject.toml to 3.10+.

Copilot uses AI. Check for mistakes.
```bash
uv run python -m cProfile -o profile.out -s cumulative \
-c "from passifypdf.encryptpdf import encrypt_pdf; encrypt_pdf('large.pdf', 'out.pdf', 'pw')"
pstats profile.out
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command "pstats profile.out" is incomplete. The pstats module requires additional commands to view the profiling data. The correct usage would be "python -m pstats profile.out" followed by interactive commands like "sort cumulative" and "stats 20", or use a one-liner like "python -m pstats profile.out -c 'sort cumulative' -c 'stats 20'".

Suggested change
pstats profile.out
uv run python -m pstats profile.out -c "sort cumulative" -c "stats 20"

Copilot uses AI. Check for mistakes.
### Proposed `pyproject.toml` change

```toml
[project.optional-dependencies]
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggested pyproject.toml syntax uses PEP 621 format ([project.optional-dependencies]), but the actual pyproject.toml file uses Poetry format ([tool.poetry]). For consistency with the existing project configuration, the suggestion should use Poetry's syntax: [tool.poetry.extras] with fast = ["cryptography>=41.0"].

Suggested change
[project.optional-dependencies]
[tool.poetry.extras]

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
@="Encrypt PDF with passifypdf"

[HKEY_CLASSES_ROOT\SystemFileAssociations\.pdf\shell\EncryptWithPassify\command]
@="cmd.exe /k \"set /p PASSWORD=Enter password: && passifypdf -i \"%1\" -o \"%~dpn1_protected.pdf\" -p \"%PASSWORD%\" -f\""
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Windows registry command uses %~dpn1 syntax which is invalid in this context. In the registry command string, %~dpn1 is Windows batch parameter expansion syntax that only works in .bat files with FOR loops or script parameters. In a registry command value, %1 represents the file path but parameter expansion modifiers like ~dpn don't work here. Use a .bat script file instead or construct the output path differently.

Suggested change
@="cmd.exe /k \"set /p PASSWORD=Enter password: && passifypdf -i \"%1\" -o \"%~dpn1_protected.pdf\" -p \"%PASSWORD%\" -f\""
@="cmd.exe /k \"set /p PASSWORD=Enter password: && passifypdf -i \"%1\" -o \"%1_protected.pdf\" -p \"%PASSWORD%\" -f\""

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
@echo off
set /p PASSWORD="Enter password: "
for %%F in (%*) do (
passifypdf -i "%%F" -o "%%~dpnF_protected.pdf" -p "%PASSWORD%" -f
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The passifypdf command includes a "-f" flag that doesn't exist in the CLI. According to the cli.py file, the available flags are -i/--input, -o/--output, -p/--passwd, and -v/--version. Remove the "-f" flag from this command.

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
@echo off
set /p PASSWORD="Enter password: "
for %%F in (%*) do (
passifypdf -i "%%F" -o "%%~dpnF_protected.pdf" -p "%PASSWORD%" -f
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Windows Send To batch script passes the user-entered password to passifypdf using -p "%PASSWORD%", which places the plaintext password on the process command line. Other local users or tools can inspect running processes and retrieve this password from the command-line arguments. Instead, passifypdf should obtain the password without exposing it in the process arguments, for example via a secure prompt or stdin-based input.

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
@="Encrypt PDF with passifypdf"

[HKEY_CLASSES_ROOT\SystemFileAssociations\.pdf\shell\EncryptWithPassify\command]
@="cmd.exe /k \"set /p PASSWORD=Enter password: && passifypdf -i \"%1\" -o \"%~dpn1_protected.pdf\" -p \"%PASSWORD%\" -f\""
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Windows registry-based context menu command embeds the password in the passifypdf -p "%PASSWORD%" argument, again exposing the plaintext password in the cmd.exe/passifypdf process command line. Any local user or malware able to inspect process arguments can recover the PDF encryption password. Update this integration to pass the password through a channel that is not visible in command-line arguments, such as a secure prompt or stdin.

Suggested change
@="cmd.exe /k \"set /p PASSWORD=Enter password: && passifypdf -i \"%1\" -o \"%~dpn1_protected.pdf\" -p \"%PASSWORD%\" -f\""
@="cmd.exe /k \"passifypdf -i \"%1\" -o \"%~dpn1_protected.pdf\" -f\""

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
PASSWORD=$(zenity --password --title="passifypdf" --text="Enter encryption password:")
for f in "$@"; do
OUTPUT="${f%.pdf}_protected.pdf"
passifypdf -i "$f" -o "$OUTPUT" -p "$PASSWORD" -f
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Nautilus script passes the zenity-collected password to passifypdf via -p "$PASSWORD", which leaks the password in the command-line arguments of the running process. Local attackers or monitoring tools can read /proc or process listings to obtain this password. Prefer a usage pattern where passifypdf reads the password from stdin or a secure prompt rather than exposing it on the command line.

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md
1. Open **Settings** → **Configure Dolphin** → **Services**.
2. In the KDE Service Menu Editor (<https://github.com/nicktindall/kde-servicemenus-editor>), add a new entry for `.pdf` files:
- Name: `Encrypt PDF with passifypdf`
- Command: `bash -c 'P=$(kdialog --password "Enter password:") && passifypdf -i %F -o "%~dpnF_protected.pdf" -p "$P" -f'`
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KDE/Dolphin service command passes the password to passifypdf using -p "$P" in the shell command, which exposes the plaintext password in the passifypdf process command line. This allows other local users or malware to read the password from process listings. Adjust the integration so that passifypdf obtains the password without placing it in command-line arguments, for example by reading from stdin or a secure password prompt.

Suggested change
- Command: `bash -c 'P=$(kdialog --password "Enter password:") && passifypdf -i %F -o "%~dpnF_protected.pdf" -p "$P" -f'`
- Command: `bash -c 'P=$(kdialog --password "Enter password:") && printf "%s" "$P" | passifypdf -i %F -o "%~dpnF_protected.pdf" -f'`

Copilot uses AI. Check for mistakes.
Comment thread docs/OS_CONTEXT_MENU.md

for f in "$@"; do
OUTPUT="${f%.pdf}_protected.pdf"
/usr/local/bin/passifypdf -i "$f" -o "$OUTPUT" -p "$PASSWORD" -f
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macOS Automator script passes the encryption password to passifypdf via the -p "$PASSWORD" command-line argument, which exposes the password in the process list to other local users or malware. An attacker with local access can read running process arguments (e.g., via Activity Monitor or ps) and recover the PDF password. To avoid leaking secrets, use a mechanism where passifypdf reads the password from a secure prompt, stdin, or another channel that does not store it in the command line.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants