diff --git a/commands/forgejo-runner-install.sh b/commands/forgejo-runner-install.sh index 66d04dc..224e406 100755 --- a/commands/forgejo-runner-install.sh +++ b/commands/forgejo-runner-install.sh @@ -176,6 +176,19 @@ case "${INSTANCE#*://}" in */*[!/]*) die "--instance takes the instance ROOT, not a repository URL: got ${INSTANCE}. Scope comes from the token, not the URL." 2 ;; esac VERSION="${VERSION#v}" +# The same sane-version charset the resolve-latest path enforces further down. +# An explicit pin skipped it entirely and went straight into the download URL, +# so a value carrying `/` or `..` was interpolated into a URL PATH rather than +# refused. Not a trust boundary — this command is already root, and the operator +# typed the flag — but a pin that cannot name a release should fail BY NAME at +# parse time, not as an opaque 404 forty lines later. install.sh's +# valid_version is the same instinct, and the asymmetry was the whole defect: +# the value rig resolves for itself was checked, the one it is handed was not. +case "$VERSION" in + "") ;; # unset — the latest release is resolved and validated below + *[!0-9.]*|.*|*.) + die "--version must be a release number like 12.13.2 (got: ${VERSION})" 2 ;; +esac [ -n "$LABELS" ] || die "--labels must not be empty" 2 # The tenant user is the default when it is there: inside a ci-box the runner