fix(deps): resolve the quick-xml advisories, unyank deep-link and spin #321

Closed
maximus wants to merge 0 commits from issue-312-313-drop-quickxml-suppressions into main
Owner

Resolves #312
Resolves #313

#312 — le declencheur avait deja saute

J'ai ecrit #312 hier en supposant qu'il fallait attendre un bump amont, sans verifier s'il existait un plist plus recent. Il en existait un :

$ cargo update --dry-run -p plist
    Updating plist v1.8.0 -> v1.10.0
    Updating quick-xml v0.38.4 -> v0.41.0

0.41.0 est exactement la version corrigee, et elle tient dans la borne actuelle de tauri — aucun changement de manifeste. RUSTSEC-2026-0194 et -0195 sont donc resolues, pas acceptees, et quittent .cargo/audit.toml le jour meme ou elles y sont entrees.

C'est le cycle de vie prevu par l'ADR 0018 : une entree part quand un correctif devient atteignable. Elle valide au passage la raison d'etre de #312 — le pendant du garde-fou, qui attrape la suppression devenue injustifiee mais pas celle devenue inutile. Ici c'est bien la seconde qui s'est produite, et sans l'issue personne ne l'aurait vue.

rsa devient la seule entree, donc CRATES="rsa" dans le garde-fou. Son commentaire de justification etait redige entierement autour de quick-xml/plist — il est re-pointe, sinon il decrirait un crate qui n'est plus dans la liste.

#313 — pourquoi 2.4.8 avait ete yankee

Le CHANGELOG amont le donne indirectement : la 2.4.9 ne contient qu'un seul commit, « Fix broken iOS custom URL schemes » (#3396).

Le defaut derriere le yank est donc iOS uniquement. Trois consequences :

  • v0.14.0 a shippe avec 2.4.8 sans jamais etre affectee — ce projet livre du desktop Windows + Linux, il n'a pas de cible mobile.
  • Le diff 2.4.8 -> 2.4.9 ne peut pas toucher nos chemins Linux/Windows, ce qui borne le risque du bump. C'est l'argument que j'oppose ici a l'absence de couverture de test sur le chemin OAuth (deep_link().on_open_url -> simpl-resultat://auth/callback), qu'aucun des 106 tests Rust n'exerce : la preuve vient du contenu du diff amont, pas d'un aller-retour manuel que je ne peux pas lancer d'ici.
  • Aucune entree CHANGELOG : ni Security (un crate yanked n'est pas une advisory), ni Fixed (rien ne change pour l'utilisateur). C'est de l'hygiene de lock.

spin 0.9.8 -> 0.9.9 suit : toutes les 0.9.0 a 0.9.8 sont yankees, ce qui ressemble a un yank en masse plutot qu'a un signal de defaut.

Les crates yanked remontent en warning et ne comptent pas dans le code de sortie de cargo audit — ce bump ne change donc pas l'etat du gate, il fait passer les warnings de 23 a 21.

Le bullet CHANGELOG de #310 est corrige, pas contredit

Les deux PR atterrissent dans le meme bloc [Unreleased] et partiront dans les memes notes de v0.15.0. Ajouter un bullet disant l'inverse du precedent aurait livre la contradiction aux utilisateurs. Le bloc n'etant pas publie, l'amender n'est pas une reecriture d'historique.

Deux affirmations y etaient fausses :

  1. « Trois autres advisories restent signalees » -> il n'en reste qu'une (rsa).
  2. « tar ... de vrais chemins de code du produit livre » -> faux. tar est bien compile, mais son chemin vulnerable (unpack_in) n'est atteint que par install_appimage et la branche macOS .app.tar.gz. Nos bundles ne passent pas par la : le .deb fait pkexec dpkg -i, le NSIS ecrit le .exe dans un temp et le lance. La moitie rustls-webpki de la phrase, elle, est correcte — TLS travaille a chaque verification de mise a jour.

Le correctif tar reste le bon geste (on ne raisonne pas autour d'une advisory quand un patch trivial existe), mais la formulation promettait une atteignabilite qu'elle n'avait pas.

ADR 0018

La decision et ses trois regles sont inchangees — seules les entrees ont bouge. Un bloc d'amendement en tete marque les passages devenus historiques, dont l'alternative « override / [patch.crates-io] impossible car plist exige ^0.38 », que plist 1.10.0 a rendue fausse le jour meme. Le principe qu'elle illustrait ([patch.crates-io] ne franchit pas une frontiere semver-incompatible) reste juste, seul le cas d'espece a disparu.

La regle du pendant est aussi durcie : toute entree doit avoir une issue portant sa condition de retrait. rsa n'en avait pas — #312 ferme, la liste serait devenue 100 % non suivie de ce cote -> #319.

Verifications

$ cargo-audit audit --file src-tauri/Cargo.lock          # depuis la RACINE
warning: 21 allowed warnings found
exit=0

$ cd src-tauri && cargo-audit audit --file Cargo.lock    # contre-epreuve
error: 1 vulnerability found!
exit=1

La seconde n'est pas une regression : .cargo/audit.toml vit a la racine et n'est lu que de la, ce qui est aussi la facon dont audit.yml l'invoque. Piege a connaitre pour quiconque relance l'audit a la main.

  • garde-fou, script extrait verbatim du YAML et lance sous bash -e : ok: rsa absent from x86_64-unknown-linux-gnu, idem windows, canari tar trouve, Suppression guard: 2 checks, exit 0
  • cargo check --all-targets vert
  • cargo test --all-targets : 106 passed, 0 failed
  • diff de lock : 4 paquets (plist, quick-xml, spin, tauri-plugin-deep-link), 666 paquets avant et apres
  • warnings 23 -> 21 : les deux entrees yanked ont disparu

Releve au passage, pas traite ici

#320 — on bundle nsis, deb et rpm, mais latest.json ne construit son entree linux-x86_64 qu'a partir du .deb (release.yml:104-122). Un utilisateur installe en rpm recoit des octets deb que Installer::Rpm rejette : il n'a aucun chemin de mise a jour automatique, alors que la mise a jour auto est une fonctionnalite Base+. Les notes de release annoncent en plus « .deb ou .AppImage » alors qu'aucun AppImage n'est construit.

#319 — declencheur de retrait pour rsa, la derniere entree de la liste.

Note de process

Le plan checker a tourne deux fois sur cette PR. Le premier tour a bloque sur l'absence d'enquete sur le motif du yank — qui s'est revelee porteuse, puisqu'elle a decide du traitement CHANGELOG. Le second a attrape la contradiction tar entre ce bullet et la doc QA de #315. Les deux items etaient invisibles depuis le diff seul.

Resolves #312 Resolves #313 ## #312 — le declencheur avait deja saute J'ai ecrit #312 hier en supposant qu'il fallait attendre un bump amont, **sans verifier s'il existait un `plist` plus recent**. Il en existait un : ``` $ cargo update --dry-run -p plist Updating plist v1.8.0 -> v1.10.0 Updating quick-xml v0.38.4 -> v0.41.0 ``` `0.41.0` est exactement la version corrigee, et elle tient dans la borne actuelle de `tauri` — aucun changement de manifeste. **RUSTSEC-2026-0194 et -0195 sont donc resolues, pas acceptees**, et quittent `.cargo/audit.toml` le jour meme ou elles y sont entrees. C'est le cycle de vie prevu par l'[ADR 0018](docs/adr/0018-suppression-advisories-non-atteignables.md) : une entree part quand un correctif devient atteignable. Elle valide au passage la raison d'etre de #312 — le pendant du garde-fou, qui attrape la suppression devenue *injustifiee* mais pas celle devenue *inutile*. Ici c'est bien la seconde qui s'est produite, et sans l'issue personne ne l'aurait vue. `rsa` devient la seule entree, donc `CRATES="rsa"` dans le garde-fou. Son commentaire de justification etait redige entierement autour de `quick-xml`/`plist` — il est re-pointe, sinon il decrirait un crate qui n'est plus dans la liste. ## #313 — pourquoi 2.4.8 avait ete yankee Le CHANGELOG amont le donne indirectement : la **2.4.9 ne contient qu'un seul commit**, « Fix broken iOS custom URL schemes » ([#3396](https://github.com/tauri-apps/plugins-workspace/pull/3396)). Le defaut derriere le yank est donc **iOS uniquement**. Trois consequences : - **v0.14.0 a shippe avec 2.4.8 sans jamais etre affectee** — ce projet livre du desktop Windows + Linux, il n'a pas de cible mobile. - Le diff 2.4.8 -> 2.4.9 **ne peut pas toucher nos chemins Linux/Windows**, ce qui borne le risque du bump. C'est l'argument que j'oppose ici a l'absence de couverture de test sur le chemin OAuth (`deep_link().on_open_url` -> `simpl-resultat://auth/callback`), qu'aucun des 106 tests Rust n'exerce : la preuve vient du contenu du diff amont, pas d'un aller-retour manuel que je ne peux pas lancer d'ici. - **Aucune entree CHANGELOG** : ni `Security` (un crate yanked n'est pas une advisory), ni `Fixed` (rien ne change pour l'utilisateur). C'est de l'hygiene de lock. `spin` 0.9.8 -> 0.9.9 suit : **toutes** les 0.9.0 a 0.9.8 sont yankees, ce qui ressemble a un yank en masse plutot qu'a un signal de defaut. Les crates yanked remontent en `warning` et **ne comptent pas dans le code de sortie** de `cargo audit` — ce bump ne change donc pas l'etat du gate, il fait passer les warnings de 23 a 21. ## Le bullet CHANGELOG de #310 est corrige, pas contredit Les deux PR atterrissent dans le **meme bloc `[Unreleased]`** et partiront dans les memes notes de v0.15.0. Ajouter un bullet disant l'inverse du precedent aurait livre la contradiction aux utilisateurs. Le bloc n'etant pas publie, l'amender n'est pas une reecriture d'historique. Deux affirmations y etaient fausses : 1. « **Trois** autres advisories restent signalees » -> il n'en reste **qu'une** (`rsa`). 2. « `tar` ... de vrais chemins de code du produit livre » -> **faux**. `tar` est bien compile, mais son chemin vulnerable (`unpack_in`) n'est atteint que par `install_appimage` et la branche macOS `.app.tar.gz`. Nos bundles ne passent pas par la : le `.deb` fait `pkexec dpkg -i`, le NSIS ecrit le `.exe` dans un temp et le lance. La moitie `rustls-webpki` de la phrase, elle, est correcte — TLS travaille a chaque verification de mise a jour. Le correctif `tar` reste le bon geste (on ne raisonne pas autour d'une advisory quand un patch trivial existe), mais la formulation promettait une atteignabilite qu'elle n'avait pas. ## ADR 0018 La decision et ses trois regles sont **inchangees** — seules les entrees ont bouge. Un bloc d'amendement en tete marque les passages devenus historiques, dont l'alternative « override / `[patch.crates-io]` impossible car `plist` exige `^0.38` », que `plist` 1.10.0 a rendue fausse le jour meme. Le principe qu'elle illustrait (`[patch.crates-io]` ne franchit pas une frontiere semver-incompatible) reste juste, seul le cas d'espece a disparu. La regle du pendant est aussi durcie : **toute** entree doit avoir une issue portant sa condition de retrait. `rsa` n'en avait pas — #312 ferme, la liste serait devenue 100 % non suivie de ce cote -> **#319**. ## Verifications ``` $ cargo-audit audit --file src-tauri/Cargo.lock # depuis la RACINE warning: 21 allowed warnings found exit=0 $ cd src-tauri && cargo-audit audit --file Cargo.lock # contre-epreuve error: 1 vulnerability found! exit=1 ``` La seconde n'est **pas** une regression : `.cargo/audit.toml` vit a la racine et n'est lu que de la, ce qui est aussi la facon dont `audit.yml` l'invoque. Piege a connaitre pour quiconque relance l'audit a la main. - garde-fou, script extrait verbatim du YAML et lance sous `bash -e` : `ok: rsa absent from x86_64-unknown-linux-gnu`, idem windows, canari `tar` trouve, `Suppression guard: 2 checks, exit 0` - `cargo check --all-targets` vert - `cargo test --all-targets` : **106 passed, 0 failed** - diff de lock : **4 paquets** (plist, quick-xml, spin, tauri-plugin-deep-link), **666 paquets avant et apres** - warnings 23 -> 21 : les deux entrees *yanked* ont disparu ## Releve au passage, pas traite ici **#320** — on bundle `nsis`, `deb` **et `rpm`**, mais `latest.json` ne construit son entree `linux-x86_64` qu'a partir du `.deb` (`release.yml:104-122`). Un utilisateur installe en rpm recoit des octets deb que `Installer::Rpm` rejette : il n'a **aucun** chemin de mise a jour automatique, alors que la mise a jour auto est une fonctionnalite Base+. Les notes de release annoncent en plus « `.deb` ou `.AppImage` » alors qu'aucun AppImage n'est construit. **#319** — declencheur de retrait pour `rsa`, la derniere entree de la liste. ## Note de process Le plan checker a tourne **deux fois** sur cette PR. Le premier tour a bloque sur l'absence d'enquete sur le motif du yank — qui s'est revelee porteuse, puisqu'elle a decide du traitement CHANGELOG. Le second a attrape la contradiction `tar` entre ce bullet et la doc QA de #315. Les deux items etaient invisibles depuis le diff seul.
maximus added 1 commit 2026-07-28 01:31:55 +00:00
fix(deps): resolve the quick-xml advisories, unyank deep-link and spin
All checks were successful
PR Check — Rust / rust (pull_request) Successful in 9m29s
108cc3801c
The removal trigger #312 was written for had already fired — I filed the issue
without checking whether a newer plist existed. plist 1.10.0 ships quick-xml
0.41.0, which carries the fix, within tauri's existing bound:

    cargo update -p plist -> plist 1.8.0 -> 1.10.0
                             quick-xml 0.38.4 -> 0.41.0

So RUSTSEC-2026-0194 and -0195 are resolved rather than accepted, and leave
.cargo/audit.toml the day they entered it. rsa is now the only entry, and the
guard loops on that crate alone; its rationale comment is re-pointed
accordingly, since it was written entirely around quick-xml/plist.

Also bumps the two yanked crates (#313). tauri-plugin-deep-link 2.4.8 -> 2.4.9:
upstream's 2.4.9 is a single commit, "Fix broken iOS custom URL schemes", so
the defect behind the yank is iOS-only and never reached this desktop app —
v0.14.0 shipping 2.4.8 was not a user-facing problem, which is why neither
Security nor Fixed applies to it in the changelog. spin 0.9.8 -> 0.9.9; every
0.9.x up to 0.9.8 is yanked, which reads as a bulk yank rather than a defect.

The #310 changelog bullet is amended rather than contradicted: it sits in the
same unreleased section and would otherwise ship two opposing claims in the
same release notes. Two of its statements were wrong. It said three advisories
remained (now one), and it said tar sits on "real code paths in the shipped
app" — tar is compiled, but its vulnerable extraction path is only reached by
the AppImage and macOS installers this project does not bundle. The
rustls-webpki half stands: TLS runs on every update check.

ADR 0018's decision is untouched; an amendment header marks the passages that
are now historical, including the "override is impossible" alternative, which
plist 1.10.0 made false the same day.

cargo audit from the repo root: 0 vulnerabilities, warnings 23 -> 21 (the two
yanked ones). From src-tauri/ it reports 1 — that is the cwd sensitivity of
.cargo/audit.toml, not a regression. Guard: 2 checks + canary, exit 0.
cargo check + cargo test green (106 tests). Lock diff: 4 packages, 666 before
and after.

Resolves #312
Resolves #313

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Author
Owner

Verdict : APPROVE

Changement de lock uniquement, sans modification de manifeste. J'ai re-vérifié chaque affirmation portante de façon indépendante — base d'advisories, manifestes crates.io, sources amont, et le log du run CI 338 — et elles tiennent toutes. Aucun point bloquant. Huit remarques suivent, dont une (n° 1) mérite une action avant de tagger v0.15.0.

Ce que j'ai vérifié plutôt que cru sur parole

Affirmation Vérification Résultat
quick-xml 0.41.0 porte le correctif advisory-db/crates/quick-xml/RUSTSEC-2026-019{4,5}.md patched = [">= 0.41.0"] sur les deux — résolues, pas contournées
plist 1.10.0 tient dans la borne API crates.io plist/1.10.0/dependencies quick-xml req=^0.41.0 — la formulation de l'amendement ADR est exacte au caractère près
rsa n'a aucun correctif advisory-db/crates/rsa/RUSTSEC-2023-0071.md patched = [] — l'entrée qualifie bien par la seconde moitié de la règle 1, pas par l'atteignabilité
L'ancienne suppression quick-xml était fondée tauri-plugin-deep-link/Cargo.toml [target.'cfg(target_os = "macos")'.build-dependencies.plist]plist est bien Apple-only malgré un parent en dépendance directe ; cargo tree -i quick-xml --target x86_64-unknown-linux-gnu vide
2.4.8 yanked / 2.4.9 non API crates.io 2.4.8 yanked=true, 2.4.9 yanked=false
spin = yank en masse API crates.io 0.9.0 → 0.9.8 toutes yanked, 0.9.9 non. Et côté sécurité RUSTSEC-2023-0031 est patched = [">= 0.9.8"], donc déjà satisfaite avant le bump : hygiène pure, confirmé
666 paquets avant/après Comptage [[package]] sur les deux locks 666 / 666
Le garde-fou tourne vraiment Log du run 338, lignes 3669-3672 ok: rsa absent from x86_64-unknown-linux-gnu, idem windows, ok: canary 'tar' found, Suppression guard: 2 checks, exit 0 — il s'exécute, il n'est pas seulement vert
Audit vert Log run 338 666 crate dependencies, 21 allowed warnings found, zéro ligne yanked, 106 tests Rust verts
Merge propre sur main d'aujourd'hui git merge-tree vs 89149d0 Aucun conflit. main a bougé de 62 fichiers depuis le merge-base 81804bb mais n'a touché ni src-tauri/, ni .cargo/, ni .forgejo/ — la CI du 28 juillet reste représentative du côté Rust

Le raisonnement de l'ADR sur le cycle de vie d'une entrée est juste, et le fait que plist déclare littéralement ^0.41.0 rend l'alternative « [patch.crates-io] impossible » caduque exactement comme l'amendement le dit.


Suggestions (aucune ne bloque)

1. Le diff de lock n'est pas de 4 paquets — il est de 4 bumps plus 7 réaiguillages windows-sys, sur du code non compilé par la CI.

Le corps annonce « diff de lock : 4 paquets ». Mesuré en comparant les arêtes de dépendance des deux locks, il y en a 7 de plus :

colored 3.1.1                 windows-sys 0.48.0 -> 0.61.2
dirs-sys 0.5.0                windows-sys 0.59.0 -> 0.61.2
errno 0.3.14                  windows-sys 0.52.0 -> 0.61.2
rustix 1.1.3                  windows-sys 0.52.0 -> 0.61.2
rustls-platform-verifier 0.6.2  windows-sys 0.52.0 -> 0.61.2
tempfile 3.24.0               windows-sys 0.52.0 -> 0.61.2
winapi-util 0.1.11            windows-sys 0.48.0 -> 0.61.2

C'est la même dérive de re-résolution que #310 avait rencontrée, et elle est bénigne pour les mêmes raisons : les 6 versions de windows-sys étaient déjà toutes dans le lock avant comme après (aucun paquet ajouté ni retiré, d'où les 666 constants), ce sont des deps cfg(windows), et cargo check --locked en CI prouve que la résolution est valide.

Ce qui mérite d'être dit quand même, c'est ça tombe : rustls-platform-verifier et tempfile sont précisément sur le chemin updater/TLS que cette PR décrit comme vivant. Or aucun job de CI ne compile Windowscheck-rust.yml tourne dans un conteneur ubuntu:22.04. Cette moitié du diff n'est donc prouvée par rien avant que release.yml ne construise la cible Windows au tag. Le mode d'échec est franc (erreur de compilation, pas un bug silencieux), donc ce n'est pas bloquant, mais ça vaut un build Windows avant de tagger v0.15.0 plutôt qu'au moment du tag.

La différence de traitement avec #310 est ce qui m'a fait regarder : cette PR-là avait explicitement borné sa dérive (« 7 pointeurs repointés vers des versions déjà présentes, 666 paquets avant/après »), celle-ci n'en parle pas.

2. L'argument de risque pour #313 est plus faible que sa conclusion — laquelle est correcte.

Le corps dit : « Le diff 2.4.8 -> 2.4.9 ne peut pas toucher nos chemins Linux/Windows », et s'appuie dessus pour se passer de couverture de test sur le chemin OAuth. J'ai diffé les deux crates dans le registre local. La conclusion tient, mais pas par ce chemin :

  • src/** est identique octet pour octet entre 2.4.8 et 2.4.9. C'est le fait le plus fort du dossier, et il n'est pas dans la PR.
  • build.rs a changé — un prédicat inversé, .filter(|domain| domain.is_app_link()).filter(|domain| !domain.is_app_link()). Mais il est à l'intérieur d'un #[cfg(any(target_os = "macos", target_os = "ios"))], donc pas compilé sur nos hôtes de build ; et tauri.conf.json ne déclare que deep-link.desktop.schemes, donc config.mobile est vide de toute façon.
  • api-iife.js a changé, et celui-là part sur toutes les plateformes — c'est le bundle JS injecté dans la webview. Delta réel : deux constantes ajoutées à l'énum d'événements (WINDOW_SUSPENDED, WINDOW_RESUMED). Purement additif ; onOpenUrl, register, getCurrent sont inchangés.

Donc le diff atteint bien nos plateformes, il ne fait juste rien d'observable. Formulation qui se défend mieux : « le seul delta qui atteint le desktop est l'ajout de deux constantes d'événement dans le bundle JS injecté ; le src/ Rust est identique octet pour octet et la retouche build.rs est cfg-gatée Apple. » Le CHANGELOG amont confirme par ailleurs le commit unique #3396.

3. L'entrée rsa ne nomme pas #319, alors que c'est cette PR qui crée la règle l'exigeant.

L'ADR gagne ici : « Toute entrée de la liste doit en avoir une ». Mais dans .cargo/audit.toml, l'entrée restante s'arrête à « Removal trigger: a fixed rsa release, or sqlx dropping the crate from the graph » — sans référence d'issue, là où l'entrée quick-xml supprimée par cette même PR portait « see #312 ». Quelqu'un qui lit le fichier ne peut pas retrouver #319. Ajouter — see #319, et étendre l'avertissement d'en-tête (« ADDING AN ENTRY HERE REQUIRES ADDING ITS CRATE TO THAT GUARD'S CRATE LIST ») pour couvrir aussi l'exigence d'issue, sinon la nouvelle règle ne vit que dans l'ADR.

4. L'amendement annonce « trois passages » historiques ; il y en a quatre.

Le corps de la règle 3 dit encore : « Un bump tauri/plist rendant quick-xml inconditionnel laisserait la suppression cacher une advisory devenue vivante ». Le commentaire équivalent dans check-rust.yml a bien été re-pointé sur rsa, l'ADR ne l'a pas été — c'est le seul endroit où les deux divergent maintenant. Au passage, la ligne de front-matter Issues: liste toujours #310/#312/#314 seuls, alors que la section Références du bas a gagné #313 et #319.

5. Sur tar, le nommage de fonction est imprécis (conclusion inchangée).

Le corps parle du « chemin vulnérable (unpack_in) ». RUSTSEC-2026-0067 déclare [affected.functions] = tar::Entry::unpack et tar::Entry::unpack_in — et le site d'appel visé, install_appimage (updater.rs:1016), utilise unpack, pas unpack_in. RUSTSEC-2026-0068 (en-têtes PAX), elle, ne déclare aucune fonction affectée : c'est un écart d'analyse syntaxique qui touche tout parsing d'archive. Les deux sites d'appel identifiés sont les bons, seule l'étiquette de fonction est à corriger.

6. Nuance sur « only reached by installer formats this app does not ship » (CHANGELOG).

Exact pour tout artefact livré, donc le texte peut rester. Mais install_appimage est le bras _ => de install_inner, pas la branche AppImage : il attrape aussi bundle_type() == None. Et bundle_type() lit __TAURI_BUNDLE_TYPE, un placeholder que le bundler tamponne — non tamponné, il rend None sur Linux et l'on retombe sur le chemin tar. Nos .deb/.rpm/NSIS sont tamponnés, donc aucun utilisateur n'est concerné ; seul un build non bundlé le serait. Ça n'appelle pas un changement de texte, mais c'est exactement le genre de détail qui a sa place dans la doc QA de #315.

7. Le glob src-tauri/** reste non prouvé.

Le point de suivi ouvert depuis #232. Cette PR touche .forgejo/workflows/check-rust.yml, qui est une entrée chemin exact des paths: — le run 338 ne permet donc toujours pas d'isoler le glob, même s'il modifie src-tauri/Cargo.lock. Le prochain candidat serait une PR touchant uniquement un fichier sous src-tauri/.

8. Fraîcheur.

La CI date du 2026-07-28 et l'audit y a chargé la base RustSec de ce jour-là. Comme #314 fait que audit.yml n'a jamais démarré, rien n'a audité ce lock depuis 17 jours ; la première chose qui le fera est la prochaine PR Rust. Rien à corriger ici, mais à savoir avant de considérer le vert comme une garantie à jour.


Conformité

  • Commit conventionnel fix(deps): … ✓ — Resolves #312 / Resolves #313
  • Aucun secret, aucune migration SQL, aucune chaîne d'interface ✓ — CHANGELOG mis à jour dans les deux langues, FR et EN cohérents ✓
  • Absence de test nouveau assumée et justifiée : il n'y a pas de logique produit dans ce diff, et le seul comportement modifié (la liste CRATES du garde-fou) est exercé en vrai par la CI, log à l'appui
  • Ne pas ajouter d'entrée CHANGELOG pour #313 est le bon arbitrage : un crate yanked n'est pas une advisory, et le défaut réparé est iOS-seulement sur une application desktop
  • Amender le bullet de #310 plutôt que le contredire est également le bon arbitrage — le bloc [Unreleased] n'est pas publié, et deux bullets contradictoires seraient partis ensemble dans les notes de v0.15.0
## Verdict : APPROVE Changement de lock uniquement, sans modification de manifeste. J'ai re-vérifié chaque affirmation portante de façon indépendante — base d'advisories, manifestes crates.io, sources amont, et le log du run CI 338 — et elles tiennent toutes. Aucun point bloquant. Huit remarques suivent, dont une (n° 1) mérite une action avant de tagger v0.15.0. ### Ce que j'ai vérifié plutôt que cru sur parole | Affirmation | Vérification | Résultat | |---|---|---| | `quick-xml` 0.41.0 porte le correctif | `advisory-db/crates/quick-xml/RUSTSEC-2026-019{4,5}.md` | `patched = [">= 0.41.0"]` sur les **deux** — résolues, pas contournées | | `plist` 1.10.0 tient dans la borne | API crates.io `plist/1.10.0/dependencies` | `quick-xml req=^0.41.0` — la formulation de l'amendement ADR est exacte au caractère près | | `rsa` n'a aucun correctif | `advisory-db/crates/rsa/RUSTSEC-2023-0071.md` | `patched = []` — l'entrée qualifie bien par la **seconde** moitié de la règle 1, pas par l'atteignabilité | | L'ancienne suppression `quick-xml` était fondée | `tauri-plugin-deep-link/Cargo.toml` | `[target.'cfg(target_os = "macos")'.build-dependencies.plist]` — `plist` est bien Apple-only malgré un parent en dépendance **directe** ; `cargo tree -i quick-xml --target x86_64-unknown-linux-gnu` vide | | 2.4.8 yanked / 2.4.9 non | API crates.io | `2.4.8 yanked=true`, `2.4.9 yanked=false` | | `spin` = yank en masse | API crates.io | 0.9.0 → 0.9.8 **toutes** yanked, 0.9.9 non. Et côté sécurité RUSTSEC-2023-0031 est `patched = [">= 0.9.8"]`, donc déjà satisfaite avant le bump : hygiène pure, confirmé | | 666 paquets avant/après | Comptage `[[package]]` sur les deux locks | 666 / 666 | | Le garde-fou tourne vraiment | Log du run 338, lignes 3669-3672 | `ok: rsa absent from x86_64-unknown-linux-gnu`, idem windows, `ok: canary 'tar' found`, `Suppression guard: 2 checks, exit 0` — il **s'exécute**, il n'est pas seulement vert | | Audit vert | Log run 338 | `666 crate dependencies`, `21 allowed warnings found`, zéro ligne `yanked`, 106 tests Rust verts | | Merge propre sur `main` d'aujourd'hui | `git merge-tree` vs `89149d0` | Aucun conflit. `main` a bougé de 62 fichiers depuis le merge-base `81804bb` mais **n'a touché ni `src-tauri/`, ni `.cargo/`, ni `.forgejo/`** — la CI du 28 juillet reste représentative du côté Rust | Le raisonnement de l'ADR sur le cycle de vie d'une entrée est juste, et le fait que `plist` déclare littéralement `^0.41.0` rend l'alternative « `[patch.crates-io]` impossible » caduque exactement comme l'amendement le dit. --- ### Suggestions (aucune ne bloque) **1. Le diff de lock n'est pas de 4 paquets — il est de 4 bumps *plus* 7 réaiguillages `windows-sys`, sur du code non compilé par la CI.** Le corps annonce « diff de lock : **4 paquets** ». Mesuré en comparant les arêtes de dépendance des deux locks, il y en a 7 de plus : ``` colored 3.1.1 windows-sys 0.48.0 -> 0.61.2 dirs-sys 0.5.0 windows-sys 0.59.0 -> 0.61.2 errno 0.3.14 windows-sys 0.52.0 -> 0.61.2 rustix 1.1.3 windows-sys 0.52.0 -> 0.61.2 rustls-platform-verifier 0.6.2 windows-sys 0.52.0 -> 0.61.2 tempfile 3.24.0 windows-sys 0.52.0 -> 0.61.2 winapi-util 0.1.11 windows-sys 0.48.0 -> 0.61.2 ``` C'est la même dérive de re-résolution que #310 avait rencontrée, et elle est bénigne pour les mêmes raisons : les 6 versions de `windows-sys` étaient déjà toutes dans le lock avant comme après (aucun paquet ajouté ni retiré, d'où les 666 constants), ce sont des deps `cfg(windows)`, et `cargo check --locked` en CI prouve que la résolution est valide. Ce qui mérite d'être dit quand même, c'est **où** ça tombe : `rustls-platform-verifier` et `tempfile` sont précisément sur le chemin updater/TLS que cette PR décrit comme vivant. Or **aucun job de CI ne compile Windows** — `check-rust.yml` tourne dans un conteneur `ubuntu:22.04`. Cette moitié du diff n'est donc prouvée par rien avant que `release.yml` ne construise la cible Windows au tag. Le mode d'échec est franc (erreur de compilation, pas un bug silencieux), donc ce n'est pas bloquant, mais ça vaut un build Windows avant de tagger v0.15.0 plutôt qu'au moment du tag. La différence de traitement avec #310 est ce qui m'a fait regarder : cette PR-là avait explicitement borné sa dérive (« 7 pointeurs repointés vers des versions déjà présentes, 666 paquets avant/après »), celle-ci n'en parle pas. **2. L'argument de risque pour #313 est plus faible que sa conclusion — laquelle est correcte.** Le corps dit : « Le diff 2.4.8 -> 2.4.9 **ne peut pas toucher nos chemins Linux/Windows** », et s'appuie dessus pour se passer de couverture de test sur le chemin OAuth. J'ai diffé les deux crates dans le registre local. La conclusion tient, mais pas par ce chemin : - `src/**` est **identique octet pour octet** entre 2.4.8 et 2.4.9. C'est le fait le plus fort du dossier, et il n'est pas dans la PR. - `build.rs` **a changé** — un prédicat inversé, `.filter(|domain| domain.is_app_link())` → `.filter(|domain| !domain.is_app_link())`. Mais il est à l'intérieur d'un `#[cfg(any(target_os = "macos", target_os = "ios"))]`, donc pas compilé sur nos hôtes de build ; et `tauri.conf.json` ne déclare que `deep-link.desktop.schemes`, donc `config.mobile` est vide de toute façon. - `api-iife.js` **a changé, et celui-là part sur toutes les plateformes** — c'est le bundle JS injecté dans la webview. Delta réel : deux constantes ajoutées à l'énum d'événements (`WINDOW_SUSPENDED`, `WINDOW_RESUMED`). Purement additif ; `onOpenUrl`, `register`, `getCurrent` sont inchangés. Donc le diff *atteint* bien nos plateformes, il ne fait juste rien d'observable. Formulation qui se défend mieux : « le seul delta qui atteint le desktop est l'ajout de deux constantes d'événement dans le bundle JS injecté ; le `src/` Rust est identique octet pour octet et la retouche `build.rs` est `cfg`-gatée Apple. » Le CHANGELOG amont confirme par ailleurs le commit unique #3396. **3. L'entrée `rsa` ne nomme pas #319, alors que c'est cette PR qui crée la règle l'exigeant.** L'ADR gagne ici : « **Toute entrée de la liste doit en avoir une** ». Mais dans `.cargo/audit.toml`, l'entrée restante s'arrête à « Removal trigger: a fixed rsa release, or sqlx dropping the crate from the graph » — sans référence d'issue, là où l'entrée `quick-xml` supprimée par cette même PR portait « see #312 ». Quelqu'un qui lit le fichier ne peut pas retrouver #319. Ajouter `— see #319`, et étendre l'avertissement d'en-tête (« ADDING AN ENTRY HERE REQUIRES ADDING ITS CRATE TO THAT GUARD'S CRATE LIST ») pour couvrir aussi l'exigence d'issue, sinon la nouvelle règle ne vit que dans l'ADR. **4. L'amendement annonce « trois passages » historiques ; il y en a quatre.** Le corps de la **règle 3** dit encore : « Un bump `tauri`/`plist` rendant `quick-xml` inconditionnel laisserait la suppression cacher une advisory devenue vivante ». Le commentaire équivalent dans `check-rust.yml` a bien été re-pointé sur `rsa`, l'ADR ne l'a pas été — c'est le seul endroit où les deux divergent maintenant. Au passage, la ligne de front-matter `Issues:` liste toujours #310/#312/#314 seuls, alors que la section Références du bas a gagné #313 et #319. **5. Sur `tar`, le nommage de fonction est imprécis (conclusion inchangée).** Le corps parle du « chemin vulnérable (`unpack_in`) ». RUSTSEC-2026-0067 déclare `[affected.functions]` = `tar::Entry::unpack` **et** `tar::Entry::unpack_in` — et le site d'appel visé, `install_appimage` (`updater.rs:1016`), utilise `unpack`, pas `unpack_in`. RUSTSEC-2026-0068 (en-têtes PAX), elle, ne déclare aucune fonction affectée : c'est un écart d'analyse syntaxique qui touche tout parsing d'archive. Les deux sites d'appel identifiés sont les bons, seule l'étiquette de fonction est à corriger. **6. Nuance sur « only reached by installer formats this app does not ship » (CHANGELOG).** Exact pour tout artefact livré, donc le texte peut rester. Mais `install_appimage` est le bras `_ =>` de `install_inner`, pas la branche AppImage : il attrape aussi `bundle_type() == None`. Et `bundle_type()` lit `__TAURI_BUNDLE_TYPE`, un placeholder que le bundler tamponne — non tamponné, il rend `None` sur Linux et l'on retombe sur le chemin `tar`. Nos `.deb`/`.rpm`/NSIS sont tamponnés, donc aucun utilisateur n'est concerné ; seul un build non bundlé le serait. Ça n'appelle pas un changement de texte, mais c'est exactement le genre de détail qui a sa place dans la doc QA de #315. **7. Le glob `src-tauri/**` reste non prouvé.** Le point de suivi ouvert depuis #232. Cette PR touche `.forgejo/workflows/check-rust.yml`, qui est une entrée **chemin exact** des `paths:` — le run 338 ne permet donc toujours pas d'isoler le glob, même s'il modifie `src-tauri/Cargo.lock`. Le prochain candidat serait une PR touchant uniquement un fichier sous `src-tauri/`. **8. Fraîcheur.** La CI date du 2026-07-28 et l'audit y a chargé la base RustSec de ce jour-là. Comme #314 fait que `audit.yml` n'a jamais démarré, **rien n'a audité ce lock depuis 17 jours** ; la première chose qui le fera est la prochaine PR Rust. Rien à corriger ici, mais à savoir avant de considérer le vert comme une garantie à jour. --- ### Conformité - Commit conventionnel `fix(deps): …` ✓ — `Resolves #312` / `Resolves #313` ✓ - Aucun secret, aucune migration SQL, aucune chaîne d'interface ✓ — CHANGELOG mis à jour dans **les deux** langues, FR et EN cohérents ✓ - Absence de test nouveau assumée et justifiée : il n'y a pas de logique produit dans ce diff, et le seul comportement modifié (la liste `CRATES` du garde-fou) est exercé en vrai par la CI, log à l'appui - Ne pas ajouter d'entrée CHANGELOG pour #313 est le bon arbitrage : un crate yanked n'est pas une advisory, et le défaut réparé est iOS-seulement sur une application desktop - Amender le bullet de #310 plutôt que le contredire est également le bon arbitrage — le bloc `[Unreleased]` n'est pas publié, et deux bullets contradictoires seraient partis ensemble dans les notes de v0.15.0
Author
Owner

Addendum à la revue ci-dessus — verdict inchangé (APPROVE)

Seconde passe indépendante. Je ne redouble pas la revue précédente, qui est plus complète que ce que j'aurais produit et dont je confirme le verdict : le garde-fou s'exécute pour de vrai (run 338, quatre lignes imprimées sur le commit de tête 108cc38), la rétractation tar est exacte — tar::Archive + entry.unpack n'existent qu'en updater.rs:1011/1016 (install_appimage) et 1228/1241 (macOS), quand install_deb part sur dpkg -i, install_rpm sur rpm -U et Windows sur zip — et tauri.conf.json:26 ne déclare que ["nsis", "deb", "rpm"].

Deux points seulement à ajouter, dont un qui retourne la suggestion n° 1.

La dérive windows-sys va dans le sens inverse de ce qui est supposé — cette PR restaure une configuration déjà éprouvée sous Windows

La suggestion n° 1 lit les 7 réaiguillages comme « la même dérive de re-résolution que #310 » et en conclut qu'il faut un build Windows avant de tagger v0.15.0, parce que rustls-platform-verifier et tempfile sont sur le chemin updater/TLS et que la CI ne compile pas Windows. Le constat sur la CI est exact, mais le sens du mouvement est l'inverse de ce qui est supposé.

#310 (f4b09b0) a fait descendre ces 7 crates depuis 0.61.2 :

$ git show f4b09b0 -- src-tauri/Cargo.lock | grep '^[+-] "windows-sys'
- "windows-sys 0.61.2",   + "windows-sys 0.48.0",
- "windows-sys 0.61.2",   + "windows-sys 0.59.0",
- "windows-sys 0.61.2",   + "windows-sys 0.52.0",     (x4)
- "windows-sys 0.61.2",   + "windows-sys 0.48.0",

Cette PR les remonte à 0.61.2. Et c'est exactement l'état du tag v0.14.0 — les 7, vérifiés un par un dans git show v0.14.0:src-tauri/Cargo.lock, y pointent tous vers windows-sys 0.61.2.

La chronologie tranche : v0.14.0 taggée le 07-18, #310 mergée le 07-27. Le build NSIS Windows de v0.14.0 a donc réellement compilé colored, dirs-sys, errno, rustix, rustls-platform-verifier, tempfile et winapi-util contre windows-sys 0.61.2.

Conséquences, dans l'ordre inverse de l'intuition :

  • la configuration non prouvée sous Windows, c'est celle que main porte aujourd'hui — la descente de #310, mergée après le dernier tag et jamais passée par un build Windows ;
  • cette PR supprime cet état non prouvé en revenant à celui qui a expédié ;
  • le build Windows préalable garde de la valeur, mais comme filet sur l'héritage de #310, pas comme réserve sur cette PR — qui réduit le risque au lieu de l'ajouter.

Le silence du corps sur ces 7 lignes reste un vrai manque, comme le dit la suggestion n° 1. Simplement, une fois nommées, elles jouent en faveur de la PR.

Le « 106 passed » sera périmé au merge

Le run 338 date du 07-28, sur une base antérieure au chantier import. src-tauri/src/lib.rs passe de 50 à 55 #[test] entre la branche et main, ce qui recoupe le 106 → 111 de STATE.md. Le merge est propre et main n'a touché aucun fichier de dépendance, donc le risque reste faible — mais rejouer cargo check + cargo test sur le résultat du merge avant de pousser, et ne pas réaffirmer 106 dans le commit de merge ou les notes.

Vérifié aussi

Les dates du texte commité sont littéralement vraies, ce qui n'allait pas de soi : .cargo/audit.toml est arrivé sur main en f4b09b0 à 19:45 -0400, ce commit est daté 21:30 -0400 le même jour. « le jour même » et « pendant quelques heures » ne sont pas des arrondis rhétoriques.

## Addendum à la revue ci-dessus — verdict inchangé (APPROVE) Seconde passe indépendante. Je ne redouble pas la revue précédente, qui est plus complète que ce que j'aurais produit et dont je confirme le verdict : le garde-fou s'exécute pour de vrai (run 338, quatre lignes imprimées sur le commit de tête `108cc38`), la rétractation `tar` est exacte — `tar::Archive` + `entry.unpack` n'existent qu'en `updater.rs:1011/1016` (`install_appimage`) et `1228/1241` (macOS), quand `install_deb` part sur `dpkg -i`, `install_rpm` sur `rpm -U` et Windows sur `zip` — et `tauri.conf.json:26` ne déclare que `["nsis", "deb", "rpm"]`. Deux points seulement à ajouter, dont un qui **retourne la suggestion n° 1**. ### La dérive `windows-sys` va dans le sens inverse de ce qui est supposé — cette PR restaure une configuration déjà éprouvée sous Windows La suggestion n° 1 lit les 7 réaiguillages comme « la même dérive de re-résolution que #310 » et en conclut qu'il faut un build Windows avant de tagger v0.15.0, parce que `rustls-platform-verifier` et `tempfile` sont sur le chemin updater/TLS et que la CI ne compile pas Windows. Le constat sur la CI est exact, mais le sens du mouvement est l'inverse de ce qui est supposé. `#310` (`f4b09b0`) a fait **descendre** ces 7 crates depuis `0.61.2` : ``` $ git show f4b09b0 -- src-tauri/Cargo.lock | grep '^[+-] "windows-sys' - "windows-sys 0.61.2", + "windows-sys 0.48.0", - "windows-sys 0.61.2", + "windows-sys 0.59.0", - "windows-sys 0.61.2", + "windows-sys 0.52.0", (x4) - "windows-sys 0.61.2", + "windows-sys 0.48.0", ``` Cette PR les **remonte** à `0.61.2`. Et c'est exactement l'état du tag `v0.14.0` — les 7, vérifiés un par un dans `git show v0.14.0:src-tauri/Cargo.lock`, y pointent tous vers `windows-sys 0.61.2`. La chronologie tranche : v0.14.0 taggée le 07-18, #310 mergée le 07-27. Le build NSIS Windows de v0.14.0 a donc **réellement compilé** `colored`, `dirs-sys`, `errno`, `rustix`, `rustls-platform-verifier`, `tempfile` et `winapi-util` contre `windows-sys 0.61.2`. Conséquences, dans l'ordre inverse de l'intuition : - la configuration non prouvée sous Windows, c'est celle que **`main` porte aujourd'hui** — la descente de #310, mergée après le dernier tag et jamais passée par un build Windows ; - cette PR **supprime** cet état non prouvé en revenant à celui qui a expédié ; - le build Windows préalable garde de la valeur, mais comme filet sur l'héritage de #310, pas comme réserve sur cette PR — qui réduit le risque au lieu de l'ajouter. Le silence du corps sur ces 7 lignes reste un vrai manque, comme le dit la suggestion n° 1. Simplement, une fois nommées, elles jouent en faveur de la PR. ### Le « 106 passed » sera périmé au merge Le run 338 date du 07-28, sur une base antérieure au chantier import. `src-tauri/src/lib.rs` passe de **50 à 55** `#[test]` entre la branche et `main`, ce qui recoupe le 106 → 111 de STATE.md. Le merge est propre et `main` n'a touché aucun fichier de dépendance, donc le risque reste faible — mais rejouer `cargo check` + `cargo test` sur le résultat du merge avant de pousser, et ne pas réaffirmer 106 dans le commit de merge ou les notes. ### Vérifié aussi Les dates du texte commité sont littéralement vraies, ce qui n'allait pas de soi : `.cargo/audit.toml` est arrivé sur `main` en `f4b09b0` à 19:45 -0400, ce commit est daté 21:30 -0400 **le même jour**. « le jour même » et « pendant quelques heures » ne sont pas des arrondis rhétoriques.
maximus force-pushed issue-312-313-drop-quickxml-suppressions from 108cc3801c to 2d4caecae8 2026-08-15 15:52:50 +00:00 Compare
Author
Owner

Mergée dans main en ff-only : 2d4caec (89149d0..97d376b). Forgejo ne détecte pas un merge local comme merged — d'où cette fermeture manuelle.

Branche rebasée sur main avant merge (elle avait 15 commits de retard). Le rebase laisse .cargo/, .forgejo/ et src-tauri/Cargo.lock identiques au byte près au commit validé par la CI run 338, et aucun commit de main n'avait touché ces chemins.

CI re-jouée sur le commit rebasé — run 370 vert, garde-fou d'audit réellement exécuté et tracé :

ok: rsa absent from x86_64-unknown-linux-gnu
ok: rsa absent from x86_64-pc-windows-msvc
ok: canary 'tar' found for x86_64-unknown-linux-gnu
Suppression guard: 2 checks, exit 0

cargo audit : 0 vulnérabilité, 22 warnings autorisés. cargo test : 111 passed, 0 failed (le « 106 » de la description était périmé — le chantier import a ajouté 5 tests).

#312 et #313 fermées automatiquement par les Resolves du message de commit.

Mergée dans `main` en **ff-only** : `2d4caec` (`89149d0..97d376b`). Forgejo ne détecte pas un merge local comme *merged* — d'où cette fermeture manuelle. Branche rebasée sur `main` avant merge (elle avait 15 commits de retard). Le rebase laisse `.cargo/`, `.forgejo/` et `src-tauri/Cargo.lock` **identiques au byte près** au commit validé par la CI run 338, et aucun commit de `main` n'avait touché ces chemins. CI re-jouée sur le commit rebasé — **run 370 vert**, garde-fou d'audit réellement exécuté et tracé : ``` ok: rsa absent from x86_64-unknown-linux-gnu ok: rsa absent from x86_64-pc-windows-msvc ok: canary 'tar' found for x86_64-unknown-linux-gnu Suppression guard: 2 checks, exit 0 ``` `cargo audit` : 0 vulnérabilité, 22 warnings autorisés. `cargo test` : **111 passed, 0 failed** (le « 106 » de la description était périmé — le chantier import a ajouté 5 tests). #312 et #313 fermées automatiquement par les `Resolves` du message de commit.
maximus closed this pull request 2026-08-15 16:13:38 +00:00
All checks were successful
PR Check — Rust / rust (pull_request) Successful in 9m23s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#321
No description provided.