fix(mangen): tolerate malformed SOURCE_DATE_EPOCH#202
Open
plusky wants to merge 1 commit into
Open
Conversation
_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.
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.
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.