The encrypted-URL route (/v1/e/) built its image request straight from the decrypted payload, applying none of the dimension bound or fit-mode check that the plain /v1/image/ route enforces. A signed token could therefore request an over-limit size (reaching libvips and exhausting memory) or an unknown fit mode (a 500 from the processor). The generator discarded every strconv.Atoi error, silently turning a non-numeric or out-of-range width, height, quality, or ttl into 0.
This adds one shared ValidateImageRequest in internal/imgcache (the max-dimension bound plus ValidateFitMode) and applies it on both routes, so an over-limit size or an unrecognized fit mode is a 400 on each. The generator now parses each numeric field explicitly, returning 400 naming the field, with width/height bounds-checked so an unusable token cannot be minted.
Not obvious from the diff:
The plain image route already rejected over-limit dimensions in its path parser, so the shared check there is defense-in-depth; it newly turns an invalid fit mode into 400 (message changes from "invalid fit mode: X" to "invalid image request: ...").
Judgement call: the generator form's existing "invalid source URL" and "failed to generate" branches now send 400 and 500 (they rendered at 200 before), a side effect of routing the new 400 through a shared, status-aware render path.
Local gate green (fmt-check, lint, test, build via the Docker builder target, run under the shared lock); hosted CI is down for infrastructure reasons.
Model: opus-4-8
The encrypted-URL route (`/v1/e/`) built its image request straight from the decrypted payload, applying none of the dimension bound or fit-mode check that the plain `/v1/image/` route enforces. A signed token could therefore request an over-limit size (reaching libvips and exhausting memory) or an unknown fit mode (a 500 from the processor). The generator discarded every `strconv.Atoi` error, silently turning a non-numeric or out-of-range `width`, `height`, `quality`, or `ttl` into 0.
This adds one shared `ValidateImageRequest` in `internal/imgcache` (the max-dimension bound plus `ValidateFitMode`) and applies it on both routes, so an over-limit size or an unrecognized fit mode is a 400 on each. The generator now parses each numeric field explicitly, returning 400 naming the field, with `width`/`height` bounds-checked so an unusable token cannot be minted.
Not obvious from the diff:
- The plain image route already rejected over-limit dimensions in its path parser, so the shared check there is defense-in-depth; it newly turns an invalid fit mode into 400 (message changes from "invalid fit mode: X" to "invalid image request: ...").
- Judgement call: the generator form's existing "invalid source URL" and "failed to generate" branches now send 400 and 500 (they rendered at 200 before), a side effect of routing the new 400 through a shared, status-aware render path.
Local gate green (fmt-check, lint, test, build via the Docker builder target, run under the shared lock); hosted CI is down for infrastructure reasons.
Model: opus-4-8
Failing tests for the missing validation on the encrypted-URL path and
the token generator: an encrypted token carrying an over-limit dimension
or an unrecognized fit mode must be rejected with 400, and POST /generate
with a non-numeric or over-limit width must return 400 rather than
minting a token. Also covers the shared imgcache validator directly.
Model: opus-4-8
The encrypted /v1/e/ route built its image request straight from the
decrypted payload, so a token could request an over-limit dimension
(reaching libvips and exhausting memory) or an unknown fit mode
(surfacing as a 500 from the processor). The token generator discarded
every strconv.Atoi error, silently turning non-numeric width, height,
quality, or ttl into 0 and applying no upper bound on dimensions.
Add a shared ValidateImageRequest in internal/imgcache enforcing the
MaxDimension bound and ValidateFitMode, and apply it on both the plain
image route and the encrypted route so both reject an over-limit size or
an unrecognized fit mode with 400. The generator now parses each numeric
field explicitly and returns 400 naming the field for non-numeric or
out-of-range input, with width and height bounds-checked so an unusable
token cannot be minted.
Model: opus-4-8
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The encrypted-URL route (
/v1/e/) built its image request straight from the decrypted payload, applying none of the dimension bound or fit-mode check that the plain/v1/image/route enforces. A signed token could therefore request an over-limit size (reaching libvips and exhausting memory) or an unknown fit mode (a 500 from the processor). The generator discarded everystrconv.Atoierror, silently turning a non-numeric or out-of-rangewidth,height,quality, orttlinto 0.This adds one shared
ValidateImageRequestininternal/imgcache(the max-dimension bound plusValidateFitMode) and applies it on both routes, so an over-limit size or an unrecognized fit mode is a 400 on each. The generator now parses each numeric field explicitly, returning 400 naming the field, withwidth/heightbounds-checked so an unusable token cannot be minted.Not obvious from the diff:
Local gate green (fmt-check, lint, test, build via the Docker builder target, run under the shared lock); hosted CI is down for infrastructure reasons.
Model: opus-4-8
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.