Skip to content

Commit 289ff6d

Browse files
fix(deps): take the fixes for sharp and shell-quote that turn main's OSV scan red (#22016)
Fixes #22013 Clause-②: no ## What this does `Validate Package Dependencies` runs OSV-Scanner against `pnpm-lock.yaml`. Two advisories published on 2026-10-06 match `main`'s lockfile, so every PR that touches a `package.json` inherits a red that is not its own (PR #22002, run 37483796939, is the first measured), and the next scheduled scan will be red too. Both advisories name a fixed version, so this PR takes both fixes. There is no exemption: `osv-scanner.toml` is untouched, because it is for advisories with no fixed release. PR #22002 is not touched here. Its `update-branch` after this lands is the PM's pointer to its holder. ## OSV reading: before and after Measured locally with OSV-Scanner **v2.3.8**, the version `validate-deps.yml` pins, in offline mode (`--offline-vulnerabilities --download-offline-databases`). The OSV npm database was downloaded on 2026-10-06 at 16:36 UTC, after both advisories were published (13:40 and 13:43 UTC). `main` at `803764a3` (exit 1). These are the two rows the card names: ```text | https://osv.dev/GHSA-wq5f-xc86-pv6w | 8.9 | npm | sharp | 0.35.4 | 0.35.5 | pnpm-lock.yaml | | https://osv.dev/GHSA-pqg4-j6r4-53mv | 9.2 | npm | shell-quote | 1.10.0 | 1.11.0 | pnpm-lock.yaml | ``` This PR at `d263b701` (exit 0): `No issues found`. One vulnerability is filtered, the standing `sprintf-js` exemption, unchanged. The scanner names nothing beyond these two advisories, so no third one has appeared since the card was filed. ## Changes ### `sharp`: the override target lifts from `^0.35.4` to `^0.35.5` - **Advisory:** GHSA-wq5f-xc86-pv6w (8.9 high). It is a memory bug in the librsvg that sharp's prebuilt binaries bundle. The range is introduced 0, fixed 0.35.5, read from the scanner's offline database. - **Edit:** the target only, `'sharp@>=0.34.0 <0.36.0': '^0.35.5'`. The selector already sits at the 0.x caret boundary, so it does not change. This is the same shape as the #16999 lift on this entry. - **Dedupe, not a forced upgrade:** `next@16.3.6` declares the optional `sharp: ^0.35.4`, which already admits 0.35.5. 0.35.4 was the single resolved copy. - **What moves with it:** sharp pins its prebuilt `@img/sharp-*` binaries exactly, so they move to 0.35.5, and the libvips binaries move to 1.3.4. - **Measured:** the installed sharp 0.35.5 loads on linux-x64. It reports `rsvg 2.63.2`, the librsvg release the advisory names as fixed, and it renders a PNG. ### `shell-quote`: a new override, `'shell-quote@>=1.8.4 <2.0.0': '^1.11.0'` - **Advisory:** GHSA-pqg4-j6r4-53mv (9.2 critical). In `quote()`, a line terminator in a string after a `{ comment }` token ends the comment, and the rest of that string runs as shell input. The range is introduced 1.8.4, fixed 1.11.0. - **The one path:** `launch-editor@2.14.1`, then `@changesets/cli@3.0.3`, then the root `package.json`'s `devDependencies`. launch-editor declares `shell-quote: ^1.8.4`, which admits the fix, so this is a dedupe onto the patched line. The copy sat on 1.10.0 through lockfile inertia. - **Selector shape:** the floor is the advisory's 1.8.4, and the bound sits at the 2.0.0 major boundary, per the block header's rule. The bound is never `<1.11.0`. - **Resolution:** `^1.11.0` floats to **1.12.0**, the newest 1.x. launch-editor calls shell-quote in one place, `parse()` on the editor command (`guess.js`). 1.11.0 and 1.12.0 only teach `parse()` ANSI-C quoting and more operators. Seven editor command strings (`code --wait`, a quoted macOS path with `-w`, `emacsclient -t -a ''` and others) parse identically under 1.10.0 and 1.12.0. The vulnerable `quote()` is never called on this path. The fix is taken anyway, because the gate reads the lockfile, not the call graph. - **Note:** the entry carries a note in the block's style, at the foot of `overrides:`. ### Why an override and not a `@changesets/cli` bump No release on that path forces the fix (`npm view`, 2026-10-06): - `@changesets/cli` 3.0.3 is npm `latest`, which is the version the root already declares. Every 3.0.x declares `launch-editor: ^2.14.1`. - launch-editor's latest, 2.14.2 (published today), declares `shell-quote: ^1.10.0`, which still admits the flagged 1.10.0. So the bump route does not exist, and a launch-editor bump would still leave the floor to lockfile inertia. On the four axes: - **Real need:** the measured need is a patched resolution and a green gate. Only the override delivers both, because no upstream release declares a range above 1.10.0. - **Long-term soundness:** the entry follows the block header's selector rule (bound at the major boundary), so a later advisory is a target-only lift. It turns into a dedupe floor once launch-editor declares `^1.11.0`. Its cost is one more ledgered entry. - **Making AI mistakes harder:** a declared floor is audited by `check:override-consistency`, and no re-lock can land below it. A bare re-lock with no floor, like #21951's `proxy-addr` step, leaves nothing to stop a later resolution from drifting back. - **Startup scope:** this is the smallest change. It moves no devDependency and adds no gate. ## Lockfile diff `pnpm-lock.yaml` is **+126/−125**, re-locked by `pnpm install`, never by hand. Every changed line falls into one of four kinds: - a `sharp`, `@img/sharp-*` or `shell-quote` package or snapshot key; - a dependency edge onto one of those packages; - the integrity line under one of those keys; - one of the two `overrides:` header lines, which are the sharp target and the new shell-quote entry. Nothing else moves. This was measured by attributing every changed line: after dropping the lines that name sharp or shell-quote, and the integrity lines under those keys, zero lines remain. `pnpm-workspace.yaml` is **+39/−1**: the sharp target, its dated note, and the shell-quote entry with its note. `pnpm why`, before and after: - `sharp` 0.35.4 becomes 0.35.5, one version in both cases. The tree shape is byte-identical with the version masked: through `next@16.3.6` under `@objectstack/docs` (and the fumadocs packages), and through better-auth's `next` peer under `@objectstack/plugin-auth`. - `shell-quote` 1.10.0 becomes 1.12.0, one version in both cases: `launch-editor@2.14.1`, then `@changesets/cli@3.0.3`, then the root's devDependencies. ## Changeset `skip-changeset`. The diff touches `pnpm-lock.yaml` and `pnpm-workspace.yaml`, both repo-root configuration, and neither is in any package's `files[]`. sharp resolves under two importers: - `@objectstack/docs`, which is private. - `@objectstack/plugin-auth`, which is published. Its `files[]` is `dist`, `README.md` and `CHANGELOG.md`, and its `package.json` does not change. It declares no sharp range at all. sharp reaches it only through better-auth 1.7.3's optional `next` peer, which this workspace auto-installs (`auto-install-peers=true`), and next's own optional `sharp` dependency. Overrides do not reach downstream installs, so nothing published changes. shell-quote is dev-only, under the private root. ## Local verification, at `d263b701` - `pnpm install --frozen-lockfile --prefer-offline`: exit 0. - The gates come from `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, derived from the change set at this head: 22 commands. The dispatch named 25 because it included `package.json`, which this diff does not touch. The `--ran` reconciliation is filled in below. `--ran` reconciliation, with exit codes recorded before any pipe: **22 derived, 18 run, 4 NOT-MEASURED, 0 UNRUN**. | Gate | Exit | |---|---| | `node scripts/check-changeset-fixed.mjs` | 0 | | `node scripts/check-closing-keyword-parity.mjs` (+ `--self-test`) | 0 / 0 | | `node scripts/check-comment-mask-corpus.mjs` | 0 | | `node scripts/check-dts-emitted.mjs --self-test` | 0 | | `node scripts/check-osv-exemptions.mjs` (+ `--self-test`) | 0 / 0 | | `node scripts/check-prerelease-pin-watch.mjs --self-test` ; `--verbose` | 0 / 0 | | `pnpm --filter @objectstack/spec run check:llms-txt` | 0 | | `pnpm check:driver-memory-census` · `check:gitlink-declared` · `check:nul-bytes` · `check:override-consistency` · `check:refd-timer-probe` · `check:vendor-export-contract-resolve` · `check:watch-hint-literal` · `check:workspace-manifest-cycles` | 0 each | | `pnpm check:dts-closure` · `check:dual-build-cjs-loads` · `check:lean-entry-closure` · `check:sourcemap-no-sources-content` | **3, PREREQUISITE NOT MET** | - **`check:override-consistency`:** the census now counts 38 overrides, up from 37. shell-quote appears in neither report: it has a consumer, and its bound clears the target floor. - **NOT MEASURED (four gates):** they read every package's built `dist/`. This diff touches no package source, so the local scope builds no package, and the build these four need is the full `pnpm build`. CI's `Build Core` and `Lint & Repo Gates` measure them on the built tree. This narrowing is declared here, and none of the four is counted as a pass. - **Not run locally, CI's:** the path-scheduled jobs that `dispatch-gates` lists (`Test Core`, `Temporal Conformance`, `Dogfood Regression Gate`, `Dogfood Verify CLI`, `Build Core`, `Build Docs`) and the type-check lanes. ## Acceptance notes - `pnpm install` prints `ioredis-mock 8.13.1: unmet peer ioredis@^5: found 6.0.0`. That warning is already on `main` and is not from this diff. - The sharp selector's floor is 0.34.0, while the new advisory's range starts at 0. No sharp copy below 0.34 resolves anywhere, and the card rules the selector untouched, so the floor stays where it is. --- _Generated by [Claude Code](https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8601526 commit 289ff6d

2 files changed

Lines changed: 165 additions & 126 deletions

File tree

0 commit comments

Comments
 (0)