Skip to content

fix(mangen): tolerate malformed SOURCE_DATE_EPOCH#202

Open
plusky wants to merge 1 commit into
openSUSE:masterfrom
plusky:fix/mangen-tolerate-bad-source-date-epoch
Open

fix(mangen): tolerate malformed SOURCE_DATE_EPOCH#202
plusky wants to merge 1 commit into
openSUSE:masterfrom
plusky:fix/mangen-tolerate-bad-source-date-epoch

Conversation

@plusky

@plusky plusky commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What

_th_date() parsed SOURCE_DATE_EPOCH with a bare int(), and
_pinned_source_date() only injects the pinned fallback when the
variable is entirely absent. A present-but-empty or non-integer value
(SOURCE_DATE_EPOCH="" or "abc", as distro build wrappers sometimes
leak) therefore reached int() unguarded, raised ValueError, and
aborted repose-mangen before a single page was written. Values that
int() accepts but the timestamp conversion cannot represent (e.g. a
leaked nanosecond epoch from date +%s%N, or anything beyond time_t)
crashed the same way inside time.gmtime() with a platform-dependent
OverflowError or OSError.

The reproducible-builds convention is to warn about an invalid
SOURCE_DATE_EPOCH and ignore it. Guard the single parse site in a new
_source_date_epoch() helper: parse and probe time.gmtime() inside one
try block, and on ValueError, OverflowError, or OSError log a warning
and fall back to the pinned epoch, so any unusable value behaves
exactly like an unset variable and generation proceeds.

_pinned_source_date(), entered once per run by main(), now resolves
the epoch up front and pins the validated value into the environment,
so the warning fires once per run instead of once per rendered page
(~10 times), and the per-page parses reuse the validated value.

Regression tests cover empty, garbage, float-like, and out-of-range
values (warn and fall back), absent (fallback date), a valid epoch
(wins, no warning), invalid-equals-absent equivalence, warn-once-per-
run, and that a full page still renders under a malformed value.
Expected dates are hardcoded literals ("2024-01-01", "2025-06-15") so
an accidental edit to the fallback constant or the strftime format
fails the tests instead of tracking along.

Verification

Full gate green (ruff format/check, ty, pytest: 560 passed, coverage 82.62%). Tests: empty, non-integer, and out-of-range values (nanosecond epochs, 20-digit values) all behave exactly like an absent variable, warn once per run (was ~10x), and generation proceeds; expected dates are hardcoded literals. Verified to fail pre-fix. Reviewed by a fan-out adversarial code review (two finder lenses per branch, two verifier lenses per finding); all confirmed findings were addressed before opening.

AI-assisted.

_th_date() parsed SOURCE_DATE_EPOCH with a bare int(), and
_pinned_source_date() only injects the pinned fallback when the
variable is entirely absent. A present-but-empty or non-integer value
(SOURCE_DATE_EPOCH="" or "abc", as distro build wrappers sometimes
leak) therefore reached int() unguarded, raised ValueError, and
aborted repose-mangen before a single page was written. Values that
int() accepts but the timestamp conversion cannot represent (e.g. a
leaked nanosecond epoch from date +%s%N, or anything beyond time_t)
crashed the same way inside time.gmtime() with a platform-dependent
OverflowError or OSError.

The reproducible-builds convention is to warn about an invalid
SOURCE_DATE_EPOCH and ignore it. Guard the single parse site in a new
_source_date_epoch() helper: parse and probe time.gmtime() inside one
try block, and on ValueError, OverflowError, or OSError log a warning
and fall back to the pinned epoch, so any unusable value behaves
exactly like an unset variable and generation proceeds.

_pinned_source_date(), entered once per run by main(), now resolves
the epoch up front and pins the validated value into the environment,
so the warning fires once per run instead of once per rendered page
(~10 times), and the per-page parses reuse the validated value.

Regression tests cover empty, garbage, float-like, and out-of-range
values (warn and fall back), absent (fallback date), a valid epoch
(wins, no warning), invalid-equals-absent equivalence, warn-once-per-
run, and that a full page still renders under a malformed value.
Expected dates are hardcoded literals ("2024-01-01", "2025-06-15") so
an accidental edit to the fallback constant or the strftime format
fails the tests instead of tracking along.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant