Skip to content

10# landed in save-session.sh only — 50-git-backup.sh still takes the octal path, where set -u makes it fatal, and a new test's docstring claims otherwise #327

Description

@fdaviddpt

Found by the release-gate audit of v0.16.0..main while cutting v0.17.0.

The code half

10# appears at scripts/save-session.sh:172, scripts/save-session.sh:604 and scripts/lib-lock.sh:412 — nowhere else in the tree.

hooks.d/after_save/50-git-backup.sh:172 keeps the bare digits-guard with no 10#. That file runs set -u, which makes the octal path fatal rather than merely skipping:

$ /bin/bash -c 'set -u; LAST_MOD=08
  case "$LAST_MOD" in ""|*[!0-9]*) LAST_MOD=0 ;; esac
  ELAPSED=$(( $(date +%s) - LAST_MOD )); echo reached; [ "$ELAPSED" -lt 900 ]; echo stamp'
/bin/bash: line 4: 08: value too great for base (error token is "08")
/bin/bash: line 5: ELAPSED: unbound variable
exit=127

The hook dies at :173, so _gb_stamp_cooldown at :583 is never reached, the marker keeps its 08, and the git backup is stopped permanently. 08/09 are all digits, so they clear the guard; they are only reachable through a corrupt marker, which is that guard's whole premise.

hooks.d/after_save/50-git-restore.sh:225 and :304 read the same way.

Class: fails-to-preserve.

The docstring half, which is the worse one

tests/test_save_session_marker_arithmetic_322.py:28-30 states that "the same 10# is added to #258's existing guard in 50-git-backup.sh".

It was not. The patch does not touch that file. A reader takes that sentence as coverage of the site that is actually still broken — and it is in a test file, which is the last place anyone re-reads for accuracy.

Class: misreports.

Related, and it is why a blind fix here would be untestable

test_a_corrupt_cooldown_marker_does_not_kill_the_hook writes to <store>/.last-git-backup-ts, while the hook reads $GB_STATE_DIR/last-git-backup-ts where GB_STATE_DIR="$BACKUP_COMMON_DIR/remember". Those paths coincide only on the REPO_ROOT fallback, which that fixture does not take.

So #258's regression is currently unguarded, and its test passes while asserting nothing about the code it names. Fix the path first; then the 08 case goes red there as it should, and the 10# fix has something to prove itself against. Doing it the other way round ships an untested change behind a test that cannot fail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions