Skip to content

Fix falsy option arguments skipping validation - #91

Open
11bit wants to merge 1 commit into
mainfrom
fix-falsy-values-skipping-validation
Open

Fix falsy option arguments skipping validation#91
11bit wants to merge 1 commit into
mainfrom
fix-falsy-values-skipping-validation

Conversation

@11bit

@11bit 11bit commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Third and last finding from the audit that produced #89 and #90: optional arguments guarded with if (value) and rendered with value || "", so any falsy value was treated as "not provided" — including invalid ones.

watermarkSize.build({ wms: { width: null, height: 100 } })
// before: "wms::100"   (silently accepted)
// after:  throws "watermark_size.width is not a number"

Swept across 11 modules: resize, size, watermark, watermarkSize, trim, unsharpMasking, pngOptions, jpegOptions, colorize, monochrome, gravity.

What changes

  • Invalid falsy values now raise. null, "" and out-of-range 0 reach their guards instead of slipping past them.
  • Explicit 0 is rendered rather than dropped. { resize: { resizing_type: "fit", width: 0, height: 100 } } now builds rs:fit:0:100 instead of rs:fit::100. Both forms mean the same thing to imgproxy — 0 and an omitted argument are both "calculate this dimension" — so no URL changes meaning. This is unlike Fix gradient dropping optional arguments set to 0 #89, where the dropped 0 genuinely differed from the default.
  • colorize.color and monochrome.color are now validated as hex colors. Neither had any type validation at all; they now match trim.color and gradient.color.
  • gravity offset checks use presence, so { type: "sm", x_offset: 0 } correctly raises gravity.type is invalid — previously only a non-zero offset triggered that check.

Bug found while sweeping

jpeg_options threw "progressive must be true if optimize_scans is true" whenever optimize_scans was merely present. With the truthiness guard that was masked; converting it to a presence check exposed it, so the cross-check is now tied to optimize_scans actually being enabled. { progressive: false, optimize_scans: false } is valid and now builds jpgo:false::::false.

Verification

  • tsc --noEmit clean, eslint src tests clean
  • vitest run → 97 files / 1114 tests passing (19 new, at least one per swept module)
  • No existing test needed changing, which suggests the truthiness behavior was never deliberate

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_01G8Aa3xeVUCaxKtQJDzZhMo

Optional arguments were guarded with `if (value)` and rendered with
`value || ""`, so falsy but invalid values such as `null` or an empty
color skipped validation and were silently rendered as omitted
arguments. Check for `undefined` instead, matching `gradient` and
`progressive_blur`.

Also validate `colorize.color` and `monochrome.color` as hex colors, and
tie the `jpeg_options` progressive cross-check to `optimize_scans` being
enabled rather than merely present.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8Aa3xeVUCaxKtQJDzZhMo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant