Repository navigation
fix(deps): this week's security advisories: pillow 13, certifi and rustls-webpki; Python 3.11 or newer → 3.148.7-alpha - #968
Merged
Conversation
…stls-webpki; Python 3.11 or newer → 3.148.7-alpha pip-audit and cargo-deny, and with them the required `dependencies` check, have been red on main and on every PR since this week's advisories. This takes all of them in one place. pillow 12.3.0 carries CVE-2026-112895, -112400, -112397, -112896, -112897, -112395, -112404 and -112899, and GitHub lists about forty more advisories published from 2026-10-17, two of them critical (among them heap overflows in the FlashPix and JPEG decoders). All are fixed only in pillow 13.0.0; there is no 12.x after 12.3.0. certifi before 2026.10.19 trusts the emSign ECC Root CA - G3, under which eight eMudhra intermediates have compromised keys (PYSEC-2026-4320, GHSA-6q48-6c7w-9gw2). The same distrust reaches Rust as RUSTSEC-2026-0381 (webpki-roots), RUSTSEC-2026-0382 (rustls-webpki) and RUSTSEC-2026-0383 (webpki-root-certs), all CVE-2026-111943. `cargo update -p` moves rustls-webpki 0.103.15 to 0.103.16 and webpki-roots and webpki-root-certs 1.0.7 to 1.0.10, and nothing else in Cargo.lock. In the sidecar locks certifi moves to 2026.10.19 with every other pin held. Its licence was re-entered by hand after reading the wheel: MPL-2.0, with a LICENSE byte-identical to 2026.7.22's. fastembed 0.9.0, the latest release, still declares pillow<13 on every Python although its code runs on 13 (qdrant/fastembed#830 lifts the cap; open and unmerged). So pillow==13.0.0 also goes in a new sidecar/requirements-override.txt, which `just lock-regen` passes to `uv pip compile --override` for the base lock only and stamps in its header. check-requirements-lock verifies the stamp, and that the file only overrides packages requirements.txt pins at the same version. Remove the override line once a fastembed release allows pillow 13. Because the lock is resolved past that cap, pip's own resolver refuses it, so every install of a lock now passes --no-deps beside --require-hashes: the base and optional-component installs in sidecar.rs, pr.yml's locked-dependency test step and release.yml's python-smoke. Every line is still pinned and hash-checked, and the lock is complete because uv resolved it. `just pip-audit` now audits the hashed locks with --disable-pip instead of installing them; on the old locks it still reports all eight pillow advisories. pillow 13 needs Python 3.11, so MIN_PYTHON goes from 3.10 to 3.11 (3.10 reaches end of life this month). The Windows and Linux installers bundle 3.12, and on a Mac PM uses the machine's Python when it is new enough and downloads its own 3.12 otherwise. So the new floor reaches only a venv an older PM built on a 3.10, which is rebuilt once on the next launch, and from-source development on a machine with nothing newer than 3.10. The setup messages now take the version from MIN_PYTHON. The locks lose the 13 package versions that existed only for Python below 3.11, and tzdata's 3.10 marker. pillow 13.0.0's wheel LICENSE is MIT-CMU plus the permissive licences of its bundled natives, byte-identical to 12.3.0's on Linux and macOS. Hardening, on any pillow: the sidecar opens a photo only as a photo format (JPEG, PNG, WebP, and HEIF once pi-heif has registered it), the one its extension names tried first. A TIFF, FlashPix, EPS or any other format renamed .jpg no longer reaches its decoder, while a PNG or WebP saved as .jpg, or a JPEG saved as .png, still reads. Without pi-heif a .heic is tried as the other three, so a real HEIC is refused and a JPEG saved as .heic still reads; any other extension is refused. The fallback that handed rapidocr the raw path when PM's own open failed is gone, since rapidocr opens a path with no such restriction. With OCR on, the pixels are decoded before the engine loads, so a file cut off halfway comes back with no size (its EXIF kept) and its row blames the file, not text recognition; with OCR off nothing decodes the pixels, as before. The photo's file is closed once it has been read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BBYU26
added a commit
that referenced
this pull request
Oct 21, 2026
BBYU26
added a commit
that referenced
this pull request
Oct 21, 2026
This was referenced Oct 21, 2026
BBYU26
added a commit
that referenced
this pull request
Oct 22, 2026
…an earlier split still overlaps → 3.148.8-alpha (C9a-3b-2 of #884) (#959) * chore(calendar): remember a split while it runs, and refuse a series an earlier split still overlaps → 3.148.7-alpha (C9a-3b-2 of #884) A "this and following" change is now recorded in the settings store before its first write (calendar_split_journal: Google's ids, the plan digest, the original's rule before and after the cut, its start) and forgotten once it lands or settles. A record no held split stands for (PM restarted) is read against Google's copies by meaning: a proven duplicate refuses what it reaches but lets "All events" delete on the new part through; a landed or changed one is said once and forgotten; one PM can't read refuses until it can. Every series read now also lists the parts PM split off it (privateExtendedProperty=pmSplitOf); one that still overlaps the original refuses every scope past "this event" (scope-M4), as does a listing PM couldn't read. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): after a restart PM offers no delete; twice needs the original's occurrences; one claim doesn't hide a record Review round 1 of C9a-3b-2, and the decided Q4 (DECISIONS 18-10): a proven duplicate only refuses, its words pointing to Google Calendar; no "All events" delete is let through. A Twice reading also needs the original still repeating from the split on, read off its occurrences as the backstop reads them (the planned series' parts, or a window listing of the original); otherwise it is said once as changed. A record is skipped as a running change's only while both its series are claimed. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): read the original whole before calling a record twice; mark running splits explicitly Review round 2 of C9a-3b-2. Reading the original from its new part now lists its exceptions and cross-checks them as gather does, so an occurrence changed on its own and left on it never counts as the rule repeating. A record is a running change's only while that send or settle has marked it in CalendarEditState.splitting; two unrelated writes holding both series no longer hide it. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): a split is marked running before its record exists; twice needs whole exceptions on both sides Review round 3 of C9a-3b-2. The running mark now goes on before the send writes its record and before a settle takes its split out of the held ones, so no look meets a record with neither. Read from the original itself, a twice reading also needs its exceptions listed whole, as from the new part. Tests pin both marks and their removal, and both unread cases. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): the overlap backstop compares instants, not days Review round 4 of C9a-3b-2: an extra date earlier on the split day stays on a cut original, and comparing days read it as overlapping the new part, refusing every change past this occurrence on a split that finished cleanly. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): the overlap backstop counts only the rule's own occurrences, by day Review round 5 of C9a-3b-2: comparing instants missed an uncut original's occurrence on the split day when the new part was retimed later that day, and still read an extra date as overlapping when the part moved earlier. Back to days, with the original's extra dates (RDATE) left out beside its stored exceptions; parts_overlap takes the master. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): the overlap backstop measures from the occurrence a part was split at Review round 6 of C9a-3b-2: measured from the new part's start, a part moved to a later day hid an uncut original whose last occurrence in the window was the split occurrence itself (a yearly event, the last of a COUNT). A new part now carries a private pmSplitAt note (with PM's other notes, ignored in every comparison), and an original overlaps while it has a live occurrence at or after that point. A cut ends it before, wherever the part moved; an extra date kept earlier that day is before it. Parts without the note fall back to their start. The RDATE exclusion is no longer needed and goes. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: 3.148.8-alpha, after the advisories PR #968 Renumbered above #968's 3.148.7-alpha now that this PR sits on it; the dependency commit it carried is in #968. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
BBYU26
added a commit
that referenced
this pull request
Oct 22, 2026
…3.148.9-alpha (C9b-1a of #884) (#960) * chore(calendar): the repeating-event dialog's parts, not yet shown → 3.148.8-alpha (C9b-1a of #884) The "which occurrences?" dialog for a repeating event is built and tested but not mounted: the pure rules and words (saveChoices.ts), the SaveChoicesDialog, the store's choices, scoped writes and settling in useEventWrites, and settle buttons on WriteNotices. Repeating events stay read-only and release builds still refuse scoped writes. Backend: a one-off Google has turned into a series is read-only with its own reason (BecameRepeating) on every path; a delete's choices that meet a changed occurrence land Google's copy; every orphan's words are said; a settle that leaves the change held answers PartialSplit with a note, so its buttons stay; one release gate for a missing choice, pinned by a source test; no jargon in what rows show. The one visible change: the became-repeating reason's wording. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): a save always names its event; refusals in the dialog are announced; notices wrap only with settle buttons Review round 1 of C9b-1a: saveEdit's title is required, so a partial notice can't read "(no title)"; the choices dialog's refusal, which arrives after it opened, is a live region whatever its tone; only a notice with settle buttons wraps them under its words, so other notices look as before; a settle with no answer keeps its notice's own offers (now tested); and the What's New line no longer says the event was made in PM. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(calendar): a settle Google turned away says the change was put back Review round 2 of C9b-1a: PM's own claim now reaches a settle as a held change with a note, so a plain busy answer only comes from Google refusing Finish's next step, after which PM took the new part back. Its words said PM was still changing the event; they now say it was put back as it was. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: 3.148.9-alpha, after the advisories PR #968 Renumbered above #959's new 3.148.8-alpha now that the stack sits on #968. Part of #884 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
This week's security advisories, in one place. The required
dependenciescheck has been red on main and on every open PR since 17-10. This PR clears all of it. 3.148.7-alpha, based on main. The calendar stack (#959 and up) will be rebased on top of it, and #959 drops its own copy of the certificate fix.What it fixes
Two decisions for you
pillow<13on every Python, although its code runs on 13. The upstream fix, chore(deps): allow pillow 13 qdrant/fastembed#830, is open and unmerged. So:sidecar/requirements-override.txt, passed touv pip compile --overridefor the base lock and stamped in its header.just requirements-lockchecks the stamp.--no-depsbeside--require-hashes. That covers the base and optional-component installs, pr.yml's locked-deps step and release.yml's python-smoke. Every line is still pinned and hash-checked, and the lock is complete because uv resolved it.just pip-auditaudits the hashed locks with--disable-pipinstead of installing them. On the old locks it still reports all eight Pillow advisories.MIN_PYTHON. The locks lose the 13 package versions that existed only for Python below 3.11.The alternative to both was to ignore the advisories until fastembed releases. I didn't take it: the JPEG and TIFF decoder bugs are reachable from any photo you drop in.
Hardening, whatever the Pillow version
.jpgno longer reaches its decoder..jpgor a JPEG saved as.heic.Reviews
.jpgwas refused) and two lows (a cut-off photo blamed on text recognition; What's New said every installer bundles Python)..heicwithout pi-heif was refused, and the photo note overstated what was lost. Both are fixed. The HEIC fix was mutation-checked.Checks
The full
just checkpasses end to end,denyandpip-auditincluded. Fresh Python 3.11, 3.12 and 3.14 venvs install the base lock with the app's flags plus--no-depsand pass the sidecar tests with fastembed required. In those venvs fastembed embeds with the default model, and markitdown converts a PNG and a PDF. The OCR lock installs on top, and with pi-heif installed a real HEIC opens.Live test for you
On the next launch of a dev or release build, PM should rebuild its document helper's environment once, because the locks changed. Then:
.jpgshows "PM could not read this image…".🤖 Generated with Claude Code