Bound clipboard payloads and image parsing

The capture daemon read the whole clipboard payload into memory and handed
it to Pillow, zbarimg and tesseract with no limit. Payloads now stream
through a capped reader (32 MiB images, 4 MiB text, 5 s deadline) and are
dropped when exceeded; image dimensions come from the container header
without decoding, and QR/OCR only run under 40 megapixels. The OCR backfill
script applies the same pixel guard. Limits are overridable via
CLIPBOARD_MAX_IMAGE_BYTES, CLIPBOARD_MAX_TEXT_BYTES, CLIPBOARD_MAX_PARSE_PIXELS.
This commit is contained in:
2026-09-08 15:20:10 +01:00
parent b1ebdb83e6
commit 4522fdbce1
3 changed files with 166 additions and 15 deletions
+11 -1
View File
@@ -11,7 +11,9 @@ import os
import shutil
import subprocess
import sys
import time
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import capture # noqa: E402 (image_size / MAX_PARSE_PIXELS shared with the daemon)
STATE = os.path.join(
os.environ.get("XDG_STATE_HOME", os.path.expanduser("~/.local/state")),
@@ -56,6 +58,14 @@ def main():
continue
if not os.path.exists(entry["path"]):
continue
# Same guard as the capture daemon: never decode an image whose header
# dimensions are unknown or above the pixel cap.
with open(entry["path"], "rb") as f:
head = f.read(65536)
size = capture.image_size(head, entry.get("mime") or "image/png")
if not size or size[0] * size[1] > capture.MAX_PARSE_PIXELS:
print(f" - {entry['id']}: skipped (size {size or 'unknown'})")
continue
text = ocr(entry["path"], args.lang)
if text:
entry["ocr"] = text