Repository navigation
Fix: Escape _ and % in search terms so they match literally - #742
Merged
axllent merged 1 commit intoOct 6, 2026
Merged
Conversation
Search terms are used in SQL LIKE patterns, where `_` and `%` are wildcards. `%` was escaped as `%%`, which is not a LIKE escape, and `_` was not escaped at all, so `to:john_doe` also matched `johnxdoe`, and deleting by that search deleted both messages. Escape `\`, `%` and `_` with a backslash and declare `ESCAPE '\'` on every LIKE in the search query builder.
Owner
|
Thanks @JayOfTheKeyboard - I appreciate the PR! I really have no idea how this slipped past for so long without being detected. I will include this in the next release at the end of the week. |
Contributor
Author
|
Thanks for the quick merge, glad it's in. |
Owner
|
This has been released in v1.31.5. Thanks for the contribution. |
elrincondehiro
pushed a commit
to elrincondehiro/web-ecommerce
that referenced
this pull request
Oct 15, 2026
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`24.19.1` → `24.19.2`](https://renovatebot.com/diffs/npm/@types%2fnode/24.19.1/24.19.2) |  |  | devDependencies | patch | | [axllent/mailpit](https://mailpit.axllent.org) ([source](https://github.com/axllent/mailpit)) | `v1.31.4` → `v1.31.5` |  |  | | patch | | [caddy](https://hub.docker.com/_/caddy) ([source](https://github.com/caddyserver/caddy-docker)) | `2.11.4-alpine` → `2.11.7-alpine` |  |  | | patch | | [eslint-plugin-svelte](https://sveltejs.github.io/eslint-plugin-svelte) ([source](https://github.com/sveltejs/eslint-plugin-svelte/tree/HEAD/packages/eslint-plugin-svelte)) | [`3.23.0` → `3.23.1`](https://renovatebot.com/diffs/npm/eslint-plugin-svelte/3.23.0/3.23.1) |  |  | dependencies | patch | | [nodemailer](https://nodemailer.com/) ([source](https://github.com/nodemailer/nodemailer)) | [`10.0.16` → `10.1.0`](https://renovatebot.com/diffs/npm/nodemailer/10.0.16/10.1.0) |  |  | devDependencies | minor | | [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.10.1` → `12.11.2`](https://renovatebot.com/diffs/npm/pnpm/12.10.1/12.11.2) |  |  | packageManager | minor | | [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm/npm/pnpm)) | [`12.10.1` → `12.11.2`](https://renovatebot.com/diffs/npm/pnpm/12.10.1/12.11.2) |  |  | engines | minor | | [prettier](https://prettier.io) ([source](https://github.com/prettier/prettier)) | [`3.9.9` → `3.9.10`](https://renovatebot.com/diffs/npm/prettier/3.9.9/3.9.10) |  |  | dependencies | patch | | [prettier](https://prettier.io) ([source](https://github.com/prettier/prettier)) | [`3.9.9` → `3.9.10`](https://renovatebot.com/diffs/npm/prettier/3.9.9/3.9.10) |  |  | devDependencies | patch | | [prettier-plugin-astro](https://github.com/withastro/prettier-plugin-astro) | [`1.1.0` → `1.1.1`](https://renovatebot.com/diffs/npm/prettier-plugin-astro/1.1.0/1.1.1) |  |  | dependencies | patch | | [renovate/renovate](https://renovatebot.com) ([source](https://github.com/renovatebot/renovate)) | [`44.149.0` → `44.151.2`](https://octochangelog.com/compare?repo=renovatebot%2Frenovate&from=44.149.0&to=44.151.2) |  |  | container | minor | --- ### Release Notes <details> <summary>axllent/mailpit</summary> ### [`v1.31.5`](https://github.com/axllent/mailpit/blob/HEAD/CHANGELOG.md#v1315) [Compare Source](https://github.com/axllent/mailpit/compare/v1.31.4...v1.31.5) ##### Chore - Add gosec #nosec annotations and set explicit Content-Type on error responses - Update Go dependencies - Update node dependencies ##### Fix - Escape `_` and `%` in search terms so they match literally ([#​742](https://github.com/axllent/mailpit/issues/742)) - Match `&` and `\` in address searches ([#​743](https://github.com/axllent/mailpit/issues/743)) - Validate AUTH parameter in MAIL FROM command ([#​744](https://github.com/axllent/mailpit/issues/744)) - MAIL FROM parameters must be space-separated per RFC 5321 ##### Test - Include additional tests for MAIL FROM parameters </details> <details> <summary>sveltejs/eslint-plugin-svelte (eslint-plugin-svelte)</summary> ### [`v3.23.1`](https://github.com/sveltejs/eslint-plugin-svelte/blob/HEAD/packages/eslint-plugin-svelte/CHANGELOG.md#3231) [Compare Source](https://github.com/sveltejs/eslint-plugin-svelte/compare/[email protected]@3.23.1) ##### Patch Changes - [#​1592](https://github.com/sveltejs/eslint-plugin-svelte/pull/1592) [`ed67eb7`](https://github.com/sveltejs/eslint-plugin-svelte/commit/ed67eb70079a3766e1fcca04717efe67b981a29c) Thanks [@​baseballyama](https://github.com/baseballyama)! - Exclude deprecated rules from the `all` configuration while keeping active rules enabled. - [#​1594](https://github.com/sveltejs/eslint-plugin-svelte/pull/1594) [`af288cd`](https://github.com/sveltejs/eslint-plugin-svelte/commit/af288cdadb7a4e9545b67301b9d28da27eb19935) Thanks [@​baseballyama](https://github.com/baseballyama)! - Recognize `browser` from SvelteKit's `$app/env` alias as a browser guard in `no-top-level-browser-globals`. - [#​1588](https://github.com/sveltejs/eslint-plugin-svelte/pull/1588) [`9814b51`](https://github.com/sveltejs/eslint-plugin-svelte/commit/9814b51df1f4a9b271b50e9abc312cd0c15e714a) Thanks [@​baseballyama](https://github.com/baseballyama)! - Include all active extension rules in the Extension Rules documentation table while preserving their primary-category entries. - [#​1589](https://github.com/sveltejs/eslint-plugin-svelte/pull/1589) [`57863c5`](https://github.com/sveltejs/eslint-plugin-svelte/commit/57863c52b3e9092a15f8432faeac9cb258b5e08d) Thanks [@​baseballyama](https://github.com/baseballyama)! - Keep the documented project service configuration consistent across TypeScript and Svelte files to avoid unnecessary project reloads. - [#​1593](https://github.com/sveltejs/eslint-plugin-svelte/pull/1593) [`4ad2c67`](https://github.com/sveltejs/eslint-plugin-svelte/commit/4ad2c67a971a76a6311ef42a091e1da76853578a) Thanks [@​baseballyama](https://github.com/baseballyama)! - Limit `require-each-key` diagnostics to the opening each tag instead of the whole block. - [#​1599](https://github.com/sveltejs/eslint-plugin-svelte/pull/1599) [`90d7b09`](https://github.com/sveltejs/eslint-plugin-svelte/commit/90d7b09cc4c075b655dfe8042cfda9158bac02f8) Thanks [@​baseballyama](https://github.com/baseballyama)! - Enable no-navigation-without-resolve on SvelteKit 3 so the recommended config reports internal links and navigation calls that omit resolve(). - [#​1590](https://github.com/sveltejs/eslint-plugin-svelte/pull/1590) [`a28563f`](https://github.com/sveltejs/eslint-plugin-svelte/commit/a28563f337515b6d32010c7f2f32d3adff730929) Thanks [@​baseballyama](https://github.com/baseballyama)! - Fix false positives in `no-immutable-reactive-statements` for TypeScript components when `ecmaFeatures.globalReturn` is enabled. - [#​1598](https://github.com/sveltejs/eslint-plugin-svelte/pull/1598) [`4607a2c`](https://github.com/sveltejs/eslint-plugin-svelte/commit/4607a2cc4065b3d6e1a10467afeb937f12f4ee55) Thanks [@​baseballyama](https://github.com/baseballyama)! - Recognize SvelteKit 3 in rule conditions, including prereleases, and document version detection and routes configuration. </details> <details> <summary>nodemailer/nodemailer (nodemailer)</summary> ### [`v10.1.0`](https://github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#1010-2026-10-10) [Compare Source](https://github.com/nodemailer/nodemailer/compare/v10.0.16...v10.1.0) ##### Features - harden message streams, SMTP connections and the connection pool ([8009da6](https://github.com/nodemailer/nodemailer/commit/8009da6e10bb8e10d7f0948a25d65895fdcd64f1)) ##### Bug Fixes - do not read the environment or the interface table on import ([094179d](https://github.com/nodemailer/nodemailer/commit/094179d176d2ebe7a28742411ad427d3c87a3981)) - end the SMTP session on any 421 reply and drive the envelope through one step ([5638ac1](https://github.com/nodemailer/nodemailer/commit/5638ac1914342460df270f736e7ceb0a844cf83a)) - keep ERR_ACCESS_DENIED from the Node.js permission model ([8b33a3d](https://github.com/nodemailer/nodemailer/commit/8b33a3d4fedee3431b97da7da12af954c3c8dceb)) - let the proxy handshake and the SMTP connection share one deadline ([91ed683](https://github.com/nodemailer/nodemailer/commit/91ed683f7a1e9ff8c56e24fb76facf16af08b162)) - **mime-node:** decode an SMTPUTF8 domain from its A-label form ([e436f4d](https://github.com/nodemailer/nodemailer/commit/e436f4dccbc8b0fb57b4747ebaafa5bb035c15cb)) - **mime-node:** finish an encoded part only after its output was read ([ec97d8f](https://github.com/nodemailer/nodemailer/commit/ec97d8f679a1d9d47bbebb03ea064f5fa6f58d01)) - **qp:** encode a lone CR or LF in binary quoted-printable parts ([42b91d9](https://github.com/nodemailer/nodemailer/commit/42b91d9a0fe18eea412c9774c5c142adf5b3efc7)) - **smtp-connection:** count the wait for the greeting against connectionTimeout ([bdcd046](https://github.com/nodemailer/nodemailer/commit/bdcd0462cab163eca3c34058d09b9981ab671c47)) - **smtp-connection:** drop the connection when DATA is taken after a refused sender ([f90fb04](https://github.com/nodemailer/nodemailer/commit/f90fb045bc24f96a128710791b2fa443e64f55fd)) - **smtp-connection:** refuse a second connect() call ([24ba2e0](https://github.com/nodemailer/nodemailer/commit/24ba2e0847ecb8202540f1c5e53483bd119ae4f2)) - turn Nagle off for SMTP sockets and report an early sendmail exit as such ([fa9b8d3](https://github.com/nodemailer/nodemailer/commit/fa9b8d300bf642cd9e11f6732ebb312c09868677)) ##### Performance Improvements - encode base64 and quoted-printable without per-chunk delays ([fd377bb](https://github.com/nodemailer/nodemailer/commit/fd377bbf559363860aedbedba6f107348fc152d2)) </details> <details> <summary>pnpm/pnpm (pnpm)</summary> ### [`v12.11.2`](https://github.com/pnpm/pnpm/releases/tag/v12.11.2): pnpm 12.11.2 [Compare Source](https://github.com/pnpm/pnpm/compare/v12.11.1...v12.11.2) This release fixes `--workspace-concurrency=Infinity`, filters set by an `updateConfig` hook, and store fetches with `enable-modules-dir=false`. ##### Patch Changes - `--workspace-concurrency=Infinity` now runs workspace projects with no concurrency limit. It used to fail with `invalid digit found in string` [#​16793](https://github.com/pnpm/pnpm/issues/16793). - `pnpm install` and other recursive commands now apply the `filter` and `filterProd` that an `updateConfig` hook sets. They used to run on every workspace project [#​16792](https://github.com/pnpm/pnpm/issues/16792). - `enable-modules-dir=false` now also fetches the packages an install reuses from an existing lockfile, so the store holds every package the lockfile lists. <!-- sponsors --> ##### Platinum Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" /> <img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> </tr> </tbody> </table> ##### Gold Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" /> <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" /> <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" /> <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a> </td> </tr> </tbody> </table> <!-- sponsors end --> ### [`v12.11.1`](https://github.com/pnpm/pnpm/releases/tag/v12.11.1): pnpm 12.11.1 [Compare Source](https://github.com/pnpm/pnpm/compare/v12.11.0...v12.11.1) This release fixes two ways `pnpm install` could fail, runs tools of any Rust release through `pnx`, and treats `registry.npmjs.com` as an alias of the npm registry. ##### Patch Changes - `pnpm install` no longer fails when `packageManager` pins the pnpm version that is already running and the registry does not publish that version. pnpm warns and continues. A registry mirror that has not synced a release no longer blocks the commands of a project pinned to it. - `pnpm install` no longer fails with `ERR_PNPM_CMD_SHIM_CHMOD` when `node_modules/.bin` holds a shim that another user created, if everyone can already execute it and it is not world-writable. This happens when several users share one checkout. - `enable-modules-dir=false` (`enableModulesDir: false` through the Node.js addon) fetches the registry packages the host can install into the store again, as pnpm v10 did, while still writing nothing under `node_modules`. The setting exists for a `node_modules` that something else mounts from the store, such as a FUSE daemon, and that consumer no longer has to download each package on first access. A plain `--lockfile-only` run still fetches nothing. - `pnpm pack` and `pnpm publish` no longer put `.npmignore` and `.gitignore` files in the tarball. A `files` entry that names one still ships it. - pnpm now treats `https://registry.npmjs.com/` as an alias of `https://registry.npmjs.org/`. Registry requests, credentials, and trusted publishing use the canonical hostname. - `pnx --package=rust@<channel> <tool>` runs a tool of that Rust release, for example `pnx --package=rust@nightly-2026-01-01 cargo build`. pnpm installs the release with the components and targets from `rust-toolchain.toml` and the target of each `--target` argument. - `pnpm install` now links agent skills for more coding agents. It detects the agent from `ANTIGRAVITY_AGENT`, `COPILOT_AGENT`, `COPILOT_CLI`, `CODEX_THREAD_ID`, `CODEX_SANDBOX`, `AI_AGENT`, and `CLAUDE_CODE` [pnpm/tasks#116](https://github.com/pnpm/tasks/issues/116). - When the registry rejects `pnpm stage publish`, the error message now starts with "Failed to stage package". <!-- sponsors --> ##### Platinum Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" /> <img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> </tr> </tbody> </table> ##### Gold Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" /> <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" /> <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" /> <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a> </td> </tr> </tbody> </table> <!-- sponsors end --> ### [`v12.11.0`](https://github.com/pnpm/pnpm/releases/tag/v12.11.0): pnpm 12.11.0 [Compare Source](https://github.com/pnpm/pnpm/compare/v12.10.1...v12.11.0) This release adds Rust toolchain management, links the agent skills that dependencies ship, adds the `permissions` setting, and keeps the colors of streamed script output. ##### Minor Changes - `pnpm install` now links the agent skills that direct dependencies ship under `skills/<name>/SKILL.md` into the project's agent skill directories, such as `.claude/skills`. A package's skills are linked only after you approve them with `pnpm approve`. The `skills.dirs` setting chooses the directories [pnpm/rfcs#35](https://github.com/pnpm/rfcs/pull/35). Added the `permissions` setting, which records what each dependency may do. Its `build` capability works like `allowBuilds` and takes precedence over it. `pnpm approve-builds` writes to `permissions` when `pnpm-workspace.yaml` already has it, and to `allowBuilds` otherwise. Added `pnpm permissions`, which lists the granted and denied permissions and the packages awaiting approval. `pnpm approve` reviews build scripts and agent skills in one prompt [pnpm/rfcs#36](https://github.com/pnpm/rfcs/pull/36). - pnpm now installs and runs Rust toolchains. - With `cargo.enabled`, `pnpm install` installs the toolchain named in `rust-toolchain.toml`. pnpm verifies the release signature, stores the toolchain once per machine, and links it into `.pnpm/rust`. `pnpm run` and `pnpm exec` put its `cargo` and `rustc` on the `PATH`. - `pnpm add -g rust@<channel>` installs a toolchain globally. The `cargo` and `rustc` commands run it outside projects that pin their own. `pnpm update -g`, `pnpm ls -g`, and `pnpm remove -g` manage it like any global package. - In a project, `pnpm add rust@<channel>` pins the toolchain in `rust-toolchain.toml`. - `pnpm shim add rust` adds project-aware shims for `cargo`, `rustc`, and the other Rust tools. In a project with a `rust-toolchain.toml`, they run the toolchain the file names and install it on first use. Elsewhere, the next command of the same name on `PATH` runs, such as rustup's. - `pnpm run` and `pnpm exec` now keep the colors of script output that they print under the project's name, such as with `--stream`. pnpm sets `FORCE_COLOR=1` for these scripts when its own output is in color, unless `FORCE_COLOR` is already set. Script output is also rendered more cleanly: - A line that a progress bar redraws with `\r` shows only its last state. - Escape codes that move the cursor or clear the screen are dropped. - Long colored lines are cut at the terminal width. - `pnpm -r run` no longer garbles its live output when a script fails while other scripts are still running. ##### Patch Changes ##### Installing packages - pnpm no longer panics with "unexpected error when polling the I/O driver" when it runs under QEMU user-mode emulation, such as a `linux/amd64` container on an Apple Silicon Mac [#​16696](https://github.com/pnpm/pnpm/issues/16696). - `pnpm view`, `pnpm update`, and other commands that read registry metadata now work behind proxies that end a response by closing the connection without a TLS `close_notify` alert [#​16704](https://github.com/pnpm/pnpm/issues/16704). - pnpm now switches to the version a project pins in `packageManager` or `devEngines.packageManager` even when `pnpm-workspace.yaml` has a setting the running pnpm cannot read, such as a `lockfile.includeResolutionSettings` section. If pnpm does not switch, it still reports that setting [#​16675](https://github.com/pnpm/pnpm/issues/16675). - When the `pnpm` package has to download its native binary on first run, it now uses the registry and credentials from `.npmrc` and from the `npm_config_registry` and `pnpm_config_registry` environment variables. `COREPACK_NPM_REGISTRY` still takes precedence. A project `.npmrc` is not read when `COREPACK_INTEGRITY_KEYS` turns off the signature check [#​16655](https://github.com/pnpm/pnpm/issues/16655). - `pnpm install` and `pnpm add --config` now apply `minimumReleaseAge` when they resolve a config dependency. A config dependency range resolves to the newest version that is old enough, so a later clean `pnpm install --frozen-lockfile` accepts the lockfile [#​16660](https://github.com/pnpm/pnpm/issues/16660). - `pnpm remove` with `catalogPrune` no longer removes catalog entries that `pnpm-lock.yaml` still records for workspace projects missing from disk. Before, a following frozen install failed with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` [#​16679](https://github.com/pnpm/pnpm/issues/16679). - With `cargo.enabled`, `pnpm install` now writes the source replacement for vendored crates into `.pnpm/crates/config.toml` and includes it as optional from `.cargo/config.toml`. A checkout without `.pnpm` builds with plain Cargo [#​16659](https://github.com/pnpm/pnpm/issues/16659). - With `nodeLinker.type` set to `loaded`, Node.js now stops with `ERR_PNPM_LOADER_UNSUPPORTED_NODE` when it preloads the store loader on a version the loader cannot serve. The supported versions are `^24.18.0 || >=26.2.0`. On other versions, CommonJS packages imported from ESM failed with `Cannot find module` on their first relative `require()`. - On Windows, `pnpm install` no longer fails with "The filename, directory name, or volume label syntax is incorrect" when a package contains a file whose name is invalid on Windows, such as `icon.svg?as=metadata.d.ts`. pnpm removes the invalid characters from the name and prints a warning that lists the renamed files. - On Windows, hoisting no longer fails intermittently with link errors when a junction is created or replaced concurrently [pnpm/tasks#53](https://github.com/pnpm/tasks/issues/53). ##### Resolving dependencies - `pnpm install --no-optional` now installs the peer dependencies a project declares when `autoInstallPeers` is on. The lockfile marked such a peer `optional: true` when another dependency had it as an optional peer. - `pnpm install` and `pnpm dedupe` now link an optional peer to the workspace package that the workspace root depends on when the picked version matches it. They installed the registry package with the same name and version [#​16706](https://github.com/pnpm/pnpm/issues/16706). - Removal overrides such as `"debug>supports-color": "-"` now also apply to an optional peer that a package declares only in `peerDependenciesMeta` [#​16681](https://github.com/pnpm/pnpm/issues/16681). - `pnpm add` and other installs that re-resolve dependencies now keep the locked `devEngines.runtime` version while it still satisfies the declared range [#​16764](https://github.com/pnpm/pnpm/issues/16764). - `pnpm audit --fix update` now updates only the dependencies whose locked version is vulnerable [#​14928](https://github.com/pnpm/pnpm/issues/14928). - `pnpm outdated` and `pnpm update --interactive` now apply `overrides` before they look up the latest version. Before, a dependency overridden to an npm alias was compared with the latest version of the package the override replaces [#​16719](https://github.com/pnpm/pnpm/issues/16719). ##### Patched dependencies - Patches saved with CRLF line endings now apply, including a patch that creates or deletes a file. pnpm rejected the git headers of such a patch with `ERR_PNPM_INVALID_PATCH` and the message `invalid file mode: 100644` [#​16641](https://github.com/pnpm/pnpm/issues/16641). - A patch that changes a file's mode, such as adding or removing the executable bit, now applies the new mode on Unix [pnpm/tasks#110](https://github.com/pnpm/tasks/issues/110). ##### Injected dependencies and deploy - With `sharedWorkspaceLockfile: false`, an injected workspace package installed in the same run as its dependent now holds only the files its `files` field selects. The copy also held other files of the project, such as `tsconfig.json` [#​16683](https://github.com/pnpm/pnpm/issues/16683). - A script listed in `syncInjectedDepsAfterScripts` no longer fails when it rewrites `package.json` while pnpm is copying its edits into the injected copies. The sync after the script now replaces a half-copied manifest. - `pnpm deploy` with a shared lockfile no longer fails with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` for `settings.dedupeInjectedDeps` or `settings.dedupePeerDependents` when `lockfile.includeResolutionSettings` is enabled. The deployed lockfile now records both settings as `false`, the values the deploy installs with. - `pnpm deploy` now writes the dependencies in the deployed `package.json` sorted by name. It also sorts the `allowBuilds` entries in the deployed `pnpm-workspace.yaml`. Repeated deploys of the same lockfile now produce identical files [#​16687](https://github.com/pnpm/pnpm/issues/16687). ##### Packing and publishing - `pnpm pack` and `pnpm publish` now match `.npmignore` and `.gitignore` rules the way npm does. A negation such as `!lib/**` or `!lib/**/!(*.map)` re-includes files under a directory that an earlier `*` rule excluded [#​16743](https://github.com/pnpm/pnpm/issues/16743). - `pnpm pack` and `pnpm publish` no longer always include root files that merely start with `README`, `LICENSE`, or `LICENCE`, such as `README_INTERNAL.md`. Only `README`, `LICENSE`, `LICENCE`, and `COPYING`, with or without an extension, ship regardless of `files` and `.npmignore`, as in npm [#​16753](https://github.com/pnpm/pnpm/issues/16753). - `pnpm publish --provenance=false` and `--no-provenance` now turn off provenance under trusted publishing, so a package can be published from a self-hosted runner. Setting `provenance: false` in `pnpm-workspace.yaml` does the same [#​16721](https://github.com/pnpm/pnpm/issues/16721). ##### Speed and resource use - `pnpm install` hardlinks files from a group-writable or world-writable store again. pnpm copied every file from such a store into `node_modules` [#​16677](https://github.com/pnpm/pnpm/issues/16677). - A repeat `pnpm install` no longer imports patched packages and packages with build scripts again when nothing changed. Their builds no longer run again either. This happened when `recursiveInstall` was `false` or the project had a `file:` dependency [#​16705](https://github.com/pnpm/pnpm/issues/16705). - Verifying the lockfile against `trustPolicy` and `minimumReleaseAge` uses less memory. pnpm no longer keeps every published version's manifest of each checked package in memory until the install ends [#​16656](https://github.com/pnpm/pnpm/issues/16656). - `pnpm rebuild <pkg>` and `pnpm rebuild --pending` no longer read the manifest of every installed package to find build scripts. Only the selected packages are inspected and built. On a large `node_modules` served lazily, such as over a network or FUSE mount, this turned a rebuild of a few packages into a fetch of every package. - `pnpm rebuild` no longer removes and recreates `node_modules` when the settings recorded in `node_modules/.modules.yaml` differ from the current configuration. The rebuild runs the build scripts against the installed packages as they are. - `pnpm store prune` now compacts the store's `index.db` after removing package entries, so the file shrinks again [#​16717](https://github.com/pnpm/pnpm/issues/16717). ##### Registry commands - `pnpm whoami`, `pnpm bugs`, `pnpm docs`, `pnpm repo`, `pnpm star`, `pnpm unstar`, and `pnpm stars` now honor the `--registry` option. - `--registry` now takes precedence over a scope's configured registry for scoped packages in `pnpm access`, `pnpm view`, `pnpm repo`, `pnpm star`, `pnpm unstar`, `pnpm owner`, `pnpm deprecate`, `pnpm undeprecate`, `pnpm unpublish`, `pnpm dist-tag`, `pnpm team`, and `pnpm stage`. Without `--registry`, `pnpm access` now sends a scoped package or scope to the registry configured for that scope. - Registry commands now keep the path of a registry URL such as `https://example.com/npm/` when they build request URLs. This applies to `pnpm access`, `pnpm owner`, `pnpm ping`, `pnpm search`, `pnpm star`, `pnpm stars`, `pnpm team`, `pnpm unstar`, and `pnpm whoami`. - `pnpm view` now honors the network retry settings. - `pnpm repo` now fetches the repository URLs of several packages in parallel. <!-- sponsors --> ##### Platinum Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> <td align="center" valign="middle"> <a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/openai_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/openai_light.svg" /> <img src="https://pnpm.io/img/users/openai_dark.svg" width="160" alt="OpenAI" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://notion.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/notion.svg" width="80" alt="Notion"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" /> <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" /> </picture> </a> </td> </tr> </tbody> </table> ##### Gold Sponsors <table> <tbody> <tr> <td align="center" valign="middle"> <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" /> <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" /> <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" /> <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" /> <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" /> <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"> <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"> <picture> <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" /> <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" /> <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> <td align="center" valign="middle"> <a href="https://latitude.so/?utm_source=pnpm&utm_medium=release_notes" target="_blank" rel="noopener noreferrer"><img src="https://pnpm.io/img/users/latitude.svg" width="160" alt="Latitude"></a> </td> </tr> </tbody> </table> <!-- sponsors end --> </details> <details> <summary>prettier/prettier (prettier)</summary> ### [`v3.9.10`](https://github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#3910) [Compare Source](https://github.com/prettier/prettier/compare/3.9.9...3.9.10) [diff](https://github.com/prettier/prettier/compare/3.9.9...3.9.10) ##### Markdown: Update `micromark-extension-gfm-table` to fix the table parse issue on performance ([#​20266](https://github.com/prettier/prettier/pull/20266) by [@​fisker](https://github.com/fisker)) See [micromark/micromark-extension-gfm-table@`4f43ead`](https://github.com/micromark/micromark-extension-gfm-table/commit/4f43ead37b786bc531d924530d4ab4c714886267) for details. </details> <details> <summary>withastro/prettier-plugin-astro (prettier-plugin-astro)</summary> ### [`v1.1.1`](https://github.com/withastro/prettier-plugin-astro/blob/HEAD/CHANGELOG.md#111) [Compare Source](https://github.com/withastro/prettier-plugin-astro/compare/v1.1.0...v1.1.1) ##### Patch Changes - [`ee01a5d`](https://github.com/withastro/prettier-plugin-astro/commit/ee01a5d): Fixes a `TypeError` ("Cannot read properties of undefined (reading 'semi')") when a comment appears before a statement inside a template expression. </details> <details> <summary>renovatebot/renovate (renovate/renovate)</summary> ### [`v44.151.2`](https://github.com/renovatebot/renovate/releases/tag/44.151.2) [Compare Source](https://github.com/renovatebot/renovate/compare/44.151.1...44.151.2) ##### Bug Fixes - **deps:** update renovate-base-image to v13.119.2 (main) ([#​46929](https://github.com/renovatebot/renovate/issues/46929)) ([f2cc80c](https://github.com/renovatebot/renovate/commit/f2cc80c7191fe99eeb06ef8ddc6cb7e2441f554a)) ##### Build System - **deps:** update dependency cronstrue to v3.29.0 (main) ([#​46930](https://github.com/renovatebot/renovate/issues/46930)) ([69a4024](https://github.com/renovatebot/renovate/commit/69a4024480ba7116efb2a18918da1ffb91878eca)) ### [`v44.151.1`](https://github.com/renovatebot/renovate/releases/tag/44.151.1) [Compare Source](https://github.com/renovatebot/renovate/compare/44.151.0...44.151.1) ##### Bug Fixes - **deps:** update renovate-base-image to v13.119.1 (main) ([#​46928](https://github.com/renovatebot/renovate/issues/46928)) ([0f8d9f6](https://github.com/renovatebot/renovate/commit/0f8d9f6de0973682147420b175506edcba002fad)) ##### Documentation - update references to python to [`b9767f5`](https://github.com/renovatebot/renovate/commit/b9767f5) (main) ([#​46927](https://github.com/renovatebot/renovate/issues/46927)) ([f9f131c](https://github.com/renovatebot/renovate/commit/f9f131cf4841edb5fa94e7ea4e936aebb55f314d)) ### [`v44.151.0`](https://github.com/renovatebot/renovate/releases/tag/44.151.0) [Compare Source](https://github.com/renovatebot/renovate/compare/44.150.1...44.151.0) ##### Features - **deps:** update renovate-base-image to v13.119.0 (main) ([#​46921](https://github.com/renovatebot/renovate/issues/46921)) ([0fe85b0](https://github.com/renovatebot/renovate/commit/0fe85b0efc80ff8e0b6bd59d092cf1799e42e0f7)) ##### Miscellaneous Chores - **deps:** update ghcr.io/containerbase/devcontainer docker tag to v14.31.2 (main) ([#​46917](https://github.com/renovatebot/renovate/issues/46917)) ([2fa8494](https://github.com/renovatebot/renovate/commit/2fa84940c5ee6079cf54176a62fa8e0bac53bee2)) ### [`v44.150.1`](https://github.com/renovatebot/renovate/releases/tag/44.150.1) [Compare Source](https://github.com/renovatebot/renovate/compare/44.150.0...44.150.1) ##### Bug Fixes - **deps:** update renovate-base-image to v13.118.4 (main) ([#​46916](https://github.com/renovatebot/renovate/issues/46916)) ([ac15d4f](https://github.com/renovatebot/renovate/commit/ac15d4fede71d906a30e58eed6c89517269097ff)) ### [`v44.150.0`](https://github.com/renovatebot/renovate/releases/tag/44.150.0) [Compare Source](https://github.com/renovatebot/renovate/compare/44.149.3...44.150.0) ##### Features - **data:** automatic update of static data ([#​46911](https://github.com/renovatebot/renovate/issues/46911)) ([0b99516](https://github.com/renovatebot/renovate/commit/0b995163fc5d72b6a883df94dc4b1dcab8e1b8da)) ##### Miscellaneous Chores - **deps:** update dependency [@​containerbase/istanbul-reports-html](https://github.com/containerbase/istanbul-reports-html) to v2.0.22 (main) ([#​46915](https://github.com/renovatebot/renovate/issues/46915)) ([5f4050a](https://github.com/renovatebot/renovate/commit/5f4050af6c33c6feb46ee0240573de21411acca0)) ### [`v44.149.3`](https://github.com/renovatebot/renovate/releases/tag/44.149.3) [Compare Source](https://github.com/renovatebot/renovate/compare/44.149.2...44.149.3) ##### Bug Fixes - **deps:** update renovate-base-image to v13.118.2 (main) ([#​46910](https://github.com/renovatebot/renovate/issues/46910)) ([dfbf52d](https://github.com/renovatebot/renovate/commit/dfbf52d31a7330279213cec6400f3120353092d9)) ##### Documentation - **github:** group App permissions by repository and organization ([#​46898](https://github.com/renovatebot/renovate/issues/46898)) ([05c7494](https://github.com/renovatebot/renovate/commit/05c74940ca85250c88ea47c0d6f999932c3ca384)) ##### Miscellaneous Chores - **deps:** update dependency pnpm to v11.28.4 (main) ([#​46907](https://github.com/renovatebot/renovate/issues/46907)) ([0d357aa](https://github.com/renovatebot/renovate/commit/0d357aa1ce1b2230e48872a48b64f587f47dea67)) - **deps:** update ghcr.io/containerbase/devcontainer docker tag to v14.31.1 (main) ([#​46908](https://github.com/renovatebot/renovate/issues/46908)) ([324e6a1](https://github.com/renovatebot/renovate/commit/324e6a1aa9263a0a2d4b366f499154cc950abde1)) - **deps:** update pnpm/setup action to v3.1.1 (main) ([#​46906](https://github.com/renovatebot/renovate/issues/46906)) ([f52a8ae](https://github.com/renovatebot/renovate/commit/f52a8ae5cf32c09505ede2d9e18c7db55fd9c802)) - **tools:** allow ambient environment in agent hook simple-git ([#​46899](https://github.com/renovatebot/renovate/issues/46899)) ([3fc4836](https://github.com/renovatebot/renovate/commit/3fc4836a87fb3c000466656cf798da3eaaadfea0)) ### [`v44.149.2`](https://github.com/renovatebot/renovate/releases/tag/44.149.2) [Compare Source](https://github.com/renovatebot/renovate/compare/44.149.1...44.149.2) ##### Bug Fixes - **cache:** build all cache keys with a shared helper ([#​46811](https://github.com/renovatebot/renovate/issues/46811)) ([f64ec39](https://github.com/renovatebot/renovate/commit/f64ec3975a4792fceae3d39af16e594f89a6a778)) - **datasource:** cache the digest per ref ([#​46819](https://github.com/renovatebot/renovate/issues/46819)) ([182de27](https://github.com/renovatebot/renovate/commit/182de2759f0bb31ee6216f4076875948d39c4c1b)) ##### Miscellaneous Chores - **deps:** update astral-sh/setup-uv action to v10.3.0 (main) ([#​46893](https://github.com/renovatebot/renovate/issues/46893)) ([0f667f9](https://github.com/renovatebot/renovate/commit/0f667f98eea2a2c9d2a187a65cab6c680f40c9e9)) ### [`v44.149.1`](https://github.com/renovatebot/renovate/releases/tag/44.149.1) [Compare Source](https://github.com/renovatebot/renovate/compare/44.149.0...44.149.1) ##### Bug Fixes - **deps:** update renovate-base-image to v13.118.1 (main) ([#​46894](https://github.com/renovatebot/renovate/issues/46894)) ([214c5f3](https://github.com/renovatebot/renovate/commit/214c5f37e73689eca387517cfd2bff00088038e1)) ##### Miscellaneous Chores - **deps:** update dependency astral-sh/uv to v0.13.0 (main) ([#​46891](https://github.com/renovatebot/renovate/issues/46891)) ([43b9758](https://github.com/renovatebot/renovate/commit/43b9758d7b429a9c6341cad519a156619f2ccf95)) - **deps:** update dependency uv to v0.13.0 (main) ([#​46892](https://github.com/renovatebot/renovate/issues/46892)) ([395bca1](https://github.com/renovatebot/renovate/commit/395bca1a0f3dddc8668c5a34feffd3aa2d75fa7d)) </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/Madrid) - Branch creation - "before 7am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNDkuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjE0OS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> --------- Co-authored-by: jacknoddy <[email protected]> Reviewed-on: https://git.hirokobu.duckdns.org/jacknoddy/web-ecommerce/pulls/44 Co-authored-by: renovate-bot <[email protected]>
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
Search terms are put into SQL
LIKEpatterns, but_and%inside the term are not escaped. In SQLiteLIKE,_matches any single character and%matches any run of characters.escPercentChar()turns%into%%, which is thefmtescape and not aLIKEescape (SQLiteLIKEhas no escape character unless the query declares one withESCAPE), so%is still a wildcard._is not touched at all.So any search containing
_or%matches more than it should._is common in email addresses, Message-IDs and tokens. BecauseDeleteSearch,SetSearchReadStatusand tag filters use the same query builder, the extra matches are also deleted, marked read or tagged.Reproduced against a fresh
developbuild (v1.31.4) with four messages:to:john_doejohn_doe@onlyjohn_doe@andjohnxdoe@john_doe@only-to:john_doejohnxdoe@dropped too)subject:"50% off"abc_def(text)token=abc_deftoken=abcXdeftoken=abc_defDELETE /api/v1/search?query=to:john_doe(2 messages,john_doe@andjohnxdoe@)The same happens for
from:,cc:,bcc:,reply-to:,addressed:,message-id:andsubject:.Fix
escPercentChar()is replaced byescLikeChars(), which escapes\,%and_with a backslash.LIKE/NOT LIKEinsearchQueryBuilder()now declaresESCAPE '\'.The backslash itself is escaped too. Otherwise a search containing a literal backslash (e.g.
subject:a\b) would turn into an escape of the next character and matchab. Before this change a backslash was matched literally, and it still is.Behaviour change: anyone who relied on
_or%acting as a wildcard (in the search box or in a tag filter's match string) will now get literal matches. Wildcards were never documented, so I treated this as a bug, but it may be worth a line in the changelog.Not changed: the
tag:filter compares with=, so it was not affected and is left as it is. The documentation already describes searches as "contains"/"has … in the field", so no doc change seemed needed.Related issues
None found. I searched open and closed issues and PRs for underscore, wildcard, percent and LIKE.
Type of change
Test plan
New
TestSearchLikeWildcards(internal/storage) stores two messages that differ only where one has a literal_or%, plus a pair for\. Every search prefix (from:,to:,cc:,bcc:,reply-to:,addressed:for each of those fields,message-id:,subject:, and plain text) must return only the literal match. The negated search must exclude only that message, andDeleteSearch("to:to_a")must leave the other three.On the parent commit this test fails 29 checks (every search and exclusion with
_/%, plus the delete) on both SQLite and rqlite. The\case passes on the parent and guards against the new escape character being left unescaped.I checked that the test catches each part of the fix: removing the
\,%or_escape, or theESCAPEclause from any one of the 26LIKEs (including each column insideaddressed:), makes it fail.TestEscPercentCharis replaced byTestEscLikeChars.gofmt -s,go vet ./..., and the CI test package list pass on SQLite and againstrqlite/rqlite:latest(MP_DATABASE=http://localhost:4001).Tests pass locally (SQLite and rqlite)
AI assistance disclosure
Please indicate whether AI tools (e.g. Claude, Copilot, ChatGPT, Cursor) were used in preparing this pull request:
If AI was used, briefly describe how (which tools, and for what parts):
Claude Code found the bug, wrote the fix and the tests, and reproduced the before/after results against a local Mailpit built from
develop. I reviewed the change and the results before submitting.Checklist