fix: reject a corrupt db.sql.gz before the destructive reset step #167

Merged
Corentin merged 1 commit from fix/demo-reset-dump-integrity into dev 2026-09-26 15:58:13 +02:00
Owner

Le defaut

demo-reset.sh verifiait l'integrite de l'archive uploads a l'etape [1/6],
avant toute destruction, mais jamais celle du dump de la base :
validate_snapshot_dir se contentait de constater que db.sql.gz existe.

Un dump tronque ou corrompu (copie ou transfert interrompu, disque plein,
dossier --snapshot assemble a la main) passait donc l'etape [1/6] —
--dry-run annoncait meme « compatible » — puis cassait en plein milieu de
l'etape [4/6], DROP/CREATE deja rejoues et base laissee dans un etat
intermediaire incoherent.

Mesure sur pile jetable, instantane de reference tronque de moitie :

Etape Lignes en base menu_slot_option
avant 761 / 24 tables 221
apres l'echec [4/6] 540 0

C'est exactement le scenario que le filet existe pour eviter, le jour de
l'oral, devant le jury.

Le correctif

validate_snapshot_dir verifie desormais sur db.sql.gz les deux memes
invariants que capture_snapshot garantit a la creation :

  • fichier non vide et flux gzip intact (gzip -t) ;
  • derniere ligne -- Dump completed — un dump tronque puis recompresse
    passerait gzip -t seul.

gzip -t plutot qu'un tube gzip -dc | tail pour que le controle ne depende
pas en silence de pipefail chez l'appelant.

Le test

tests/shell/demo-snapshot-lib.test.sh couvre validate_snapshot_dir sans
Docker (la fonction ne lit que des fichiers) : 14 assertions, dont 4 echouent
sur la version precedente. Un job shell-tests les execute en CI.

Verification

Filet exerce de bout en bout sur une pile jetable (wakdodemoverif), production
jamais touchee : instantane pris (24 tables, 761 lignes), refus sur schema
divergent dans les deux sens (code 3), identite de cible divergente (code 7),
--dry-run sans effet, remise a zero apres degat verifiee table par table,
sauvegarde de securite restaurable (retour arriere reussi), sessions PHP
invalidees (401 apres reset sur un cookie valide avant), images restaurees au
md5 pres.

## Le defaut `demo-reset.sh` verifiait l'integrite de l'archive uploads a l'etape `[1/6]`, avant toute destruction, mais jamais celle du dump de la base : `validate_snapshot_dir` se contentait de constater que `db.sql.gz` existe. Un dump tronque ou corrompu (copie ou transfert interrompu, disque plein, dossier `--snapshot` assemble a la main) passait donc l'etape `[1/6]` — `--dry-run` annoncait meme « compatible » — puis cassait en plein milieu de l'etape `[4/6]`, `DROP`/`CREATE` deja rejoues et base laissee dans un etat intermediaire incoherent. Mesure sur pile jetable, instantane de reference tronque de moitie : | Etape | Lignes en base | `menu_slot_option` | |---|---|---| | avant | 761 / 24 tables | 221 | | apres l'echec `[4/6]` | **540** | **0** | C'est exactement le scenario que le filet existe pour eviter, le jour de l'oral, devant le jury. ## Le correctif `validate_snapshot_dir` verifie desormais sur `db.sql.gz` les deux memes invariants que `capture_snapshot` garantit a la creation : - fichier non vide et flux gzip intact (`gzip -t`) ; - derniere ligne `-- Dump completed` — un dump tronque puis recompresse passerait `gzip -t` seul. `gzip -t` plutot qu'un tube `gzip -dc | tail` pour que le controle ne depende pas en silence de `pipefail` chez l'appelant. ## Le test `tests/shell/demo-snapshot-lib.test.sh` couvre `validate_snapshot_dir` sans Docker (la fonction ne lit que des fichiers) : 14 assertions, dont 4 echouent sur la version precedente. Un job `shell-tests` les execute en CI. ## Verification Filet exerce de bout en bout sur une pile jetable (`wakdodemoverif`), production jamais touchee : instantane pris (24 tables, 761 lignes), refus sur schema divergent dans les deux sens (code 3), identite de cible divergente (code 7), `--dry-run` sans effet, remise a zero apres degat verifiee table par table, sauvegarde de securite restaurable (retour arriere reussi), sessions PHP invalidees (401 apres reset sur un cookie valide avant), images restaurees au md5 pres.
fix: reject a corrupt db.sql.gz before the destructive reset step
All checks were successful
CI / secret-scan (push) Successful in 26s
CI / php-lint (push) Successful in 27s
CI / static-tests (push) Successful in 2m30s
CI / js-tests (push) Successful in 42s
CI / shell-tests (push) Successful in 7s
CI / secret-scan (pull_request) Successful in 23s
CI / php-lint (pull_request) Successful in 25s
CI / static-tests (pull_request) Successful in 2m29s
CI / js-tests (pull_request) Successful in 39s
CI / shell-tests (pull_request) Successful in 6s
4b1cdb8cf1
demo-reset.sh checked the integrity of the uploads archive at step [1/6], before
any destruction, but never that of the database dump itself: validate_snapshot_dir
only asserted that db.sql.gz existed. A truncated or corrupt dump (interrupted
copy or transfer, full disk, hand-assembled --snapshot directory) therefore passed
step [1/6] - --dry-run even reported "compatible" - and then broke in the middle of
step [4/6], with the DROP/CREATE already replayed and the database left in an
incoherent intermediate state. Measured on a throwaway stack: 540 rows left out of
761, menu_slot_option emptied (0 instead of 221).

validate_snapshot_dir now asserts on db.sql.gz the same two invariants that
capture_snapshot guarantees at creation time: a non-empty file with an intact gzip
stream (gzip -t), and a dump whose last line is "-- Dump completed" (a dump
truncated then recompressed would pass gzip -t alone). gzip -t rather than a
gzip -dc pipe so the check does not silently depend on the caller having pipefail.

tests/shell/demo-snapshot-lib.test.sh covers validate_snapshot_dir without Docker
(the function only reads files): 14 assertions, 4 of which fail on the previous
version. A shell-tests job runs them in CI.
Corentin scheduled this pull request to auto merge when all checks succeed 2026-09-26 15:50:49 +02:00
Sign in to join this conversation.
No reviewers
No labels
auto-merge
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
AcadeNice/corentin_wakdo!167
No description provided.