Require strict ISO 8601 in the age backstop; document the no-stable-release stance
GNU date accepts relative expressions like '2 days ago', which would let a buggy hook fabricate a release age; the backstop now insists on an ISO 8601 timestamp before date parses it. The provider header now states, rather than contradicts, the code's behavior for a feed with no stable releases: that is a loud failure by design, while quarantined releases report no update.
This commit is contained in:
+11
-1
@@ -171,7 +171,11 @@ release_age_status() {
|
||||
[[ "${BYPASS_MIN_RELEASE_AGE:-}" != "1" ]] || return 0
|
||||
local published_at published_epoch
|
||||
published_at=$(jq -r '.published_at // empty' <<<"$release")
|
||||
if [[ -z "$published_at" ]] || ! published_epoch=$(date --date="$published_at" +%s 2>/dev/null); then
|
||||
# Strict ISO 8601 before GNU date sees it: date also accepts relative
|
||||
# expressions like "2 days ago", which would let a buggy hook fabricate an
|
||||
# age instead of failing closed.
|
||||
if [[ ! "$published_at" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?(Z|[+-][0-9]{2}:?[0-9]{2})$ ]] \
|
||||
|| ! published_epoch=$(date --date="$published_at" +%s 2>/dev/null); then
|
||||
return 2
|
||||
fi
|
||||
(( $(date +%s) - published_epoch >= min_age )) || return 1
|
||||
@@ -573,6 +577,12 @@ EOF
|
||||
rel=$(jq -n '{pkgver: "2.0.0", sha256sums: {}}')
|
||||
st=0; release_age_status "$rel" 86400 || st=$?
|
||||
check "missing published_at is unprovable" "2" "$st"
|
||||
rel=$(jq -n '{pkgver: "2.0.0", published_at: "2 days ago", sha256sums: {}}')
|
||||
st=0; release_age_status "$rel" 86400 || st=$?
|
||||
check "relative-date expression is unprovable, not an age" "2" "$st"
|
||||
rel=$(jq -n --arg p "$(date -u -d '2 days ago' +%Y-%m-%dT%H:%M:%S+00:00)" '{pkgver: "1.9.0", published_at: $p, sha256sums: {}}')
|
||||
st=0; release_age_status "$rel" 86400 || st=$?
|
||||
check "numeric-offset ISO timestamp passes" "0" "$st"
|
||||
|
||||
echo "Duration parser:"
|
||||
local agepkg="$TEMP_DIR/selftest-age"
|
||||
|
||||
@@ -29,8 +29,10 @@ package_upstream_github_repo() {
|
||||
# Fetches sit behind functions so the self-test can replace them with fixture
|
||||
# readers; everything below the fetch is deterministic and testable offline.
|
||||
# Only the 100 most recent releases are considered -- a bounded search, not
|
||||
# pagination. A feed whose entire first page is drafts, prereleases, or
|
||||
# quarantined releases reports no update and waits for the next run.
|
||||
# pagination. Quarantined releases report no update and wait for the next
|
||||
# run; a page with no stable release at all (drafts and prereleases only)
|
||||
# fails the sync instead, because a provider-tracked feed suddenly shipping
|
||||
# nothing stable is an anomaly worth a loud error, not a silent skip.
|
||||
github_fetch_releases() {
|
||||
local repo="$1"
|
||||
curl -fsSL "https://api.github.com/repos/$repo/releases?per_page=100"
|
||||
|
||||
Reference in New Issue
Block a user