diff --git a/README.md b/README.md index 8f1e261..5a1785c 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,8 @@ Where: or `85` when the URL has no `q`; a request whose `q` is anything else is refused with 400 - `fit` — the URL's `fit` query parameter (cover, contain, fill, inside, - outside), or `cover` when the URL has no `fit` + outside), or `cover` when the URL has no `fit`; a request whose `fit` is + anything else, an empty `fit=` included, is refused with 400 **Example:** resize `https://cdn.example.com/photos/cat.jpg` to 800x600 WebP with expiration 1704067200, default quality and fit: diff --git a/TODO.md b/TODO.md index 736c4e1..a327b56 100644 --- a/TODO.md +++ b/TODO.md @@ -30,6 +30,12 @@ exhaustion # Completed Steps +- 2026-09-28 refuse an empty `fit` on `/v1/image/` (closes #139): a + `fit` in the URL with an empty value (`fit=`) is a 400 naming `fit`, + instead of being served as `cover` and verified against a signature + made for `cover`; only a `fit` missing from the URL is still `cover`; + any other value still goes through the existing fit-mode check; + `README.md` says so where it documents `fit`. - 2026-09-28 refuse an invalid `q` on `/v1/image/` (closes #134): a `q` that is not a whole number from 1 to 100, an empty `q` included, is a 400 naming `q` and the value, instead of being served at the default diff --git a/internal/handlers/image.go b/internal/handlers/image.go index f8a1e64..5139905 100644 --- a/internal/handlers/image.go +++ b/internal/handlers/image.go @@ -144,8 +144,14 @@ func (s *Handlers) parseImageRequest( return nil, false } - if fit := query.Get("fit"); fit != "" { - req.FitMode = imgcache.FitMode(fit) + // Only a fit missing from the URL is cover. A fit in the URL that is not a + // fit mode is refused by the fit-mode check below; that check would take an + // empty fit as missing, so an empty one is refused here. + req.FitMode = imgcache.FitMode(query.Get("fit")) + if query.Has("fit") && req.FitMode == "" { + s.respondError(w, `invalid fit: not a fit mode, got ""`, http.StatusBadRequest) + + return nil, false } // Default fit mode if not set