Skip to content

fix(de-DE,nl-NL): guard scale ceilings in the Germanic pair#358

Merged
TylerVigario merged 1 commit into
mainfrom
fix/germanic-scale-ceilings
Jun 4, 2026
Merged

fix(de-DE,nl-NL): guard scale ceilings in the Germanic pair#358
TylerVigario merged 1 commit into
mainfrom
fix/germanic-scale-ceilings

Conversation

@TylerVigario
Copy link
Copy Markdown
Collaborator

Tenth in the fix-then-gate series. German + Dutch.

What fuzzing found

Both emit "undefined" past their long-scale vocabulary:

cardinal ordinal currency
de-DE 10³⁰ 10³⁰ (cardinal + ste) 10³⁰
nl-NL 10³⁰ 10²¹ 10³⁰

de-DE is uniform (ordinal/currency build on the cardinal). nl-NL's ordinal caps lower because it uses a shorter SCALE_ORDINAL table (like pt) — for a number whose lowest non-zero group is a scale group.

Fix

Entry-point pattern. Cardinal ceiling derived from SCALES ((length + 1) * 3, indexed from duizend/tausend at 10³). nl's SCALE_ORDINAL hoisted to module scope so its .length derives MAX_ORDINAL (and it's no longer rebuilt per call). Decimal guarded in both (integer-spelled fractions).

Verification

Per locale: well-formed string or RangeError across ±10⁴⁰; integer/ordinal/decimal boundaries confirm ceil−1 ok / ceil throws (de ord 10³⁰, nl ord 10²¹). Existing fixtures green, lint clean, 269 tests.

🤖 Generated with Claude Code

Both emit "undefined" past their long-scale vocabulary.

- de-DE: uniform 10^30 across all three forms (ordinal = cardinal +
  "ste" suffix; currency builds on cardinal). SCALES indexed
  [scaleIndex-1] from 'tausend' -> ceiling (SCALES.length+1)*3 = 10^30.
- nl-NL: cardinal/currency 10^30, but ordinal 10^21 — its ordinal uses a
  shorter SCALE_ORDINAL table (hoisted to module scope; ceiling derives
  from its length and it's no longer rebuilt per call).

Entry-point pattern; decimal guarded (both spell the fraction via
integerToWords(BigInt(remainder))).

Verified per locale (well-formed or RangeError; integer/ordinal/decimal
boundaries); full suite green (269).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 4, 2026 14:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the German (de-DE) and Dutch (nl-NL) locale converters by adding scale-ceiling guards at the public entry points so inputs beyond each locale’s supported long-scale vocabulary throw a uniform RangeError instead of producing malformed output (e.g., "undefined").

Changes:

  • Add tooLargeError-based magnitude checks to toCardinal, toOrdinal, and toCurrency for de-DE and nl-NL (including decimal significant digits where decimals are spelled via the scale builder).
  • Derive ceiling thresholds directly from each locale’s scale tables (and for nl-NL, from a hoisted SCALE_ORDINAL), keeping limits consistent with the vocabulary.
  • Hoist nl-NL SCALE_ORDINAL to module scope to avoid rebuilding it per call and to support deriving MAX_ORDINAL.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/nl-NL.js Adds derived cardinal/ordinal ceilings (incl. decimal significant digits), hoists SCALE_ORDINAL, and applies tooLargeError guards at entry points.
src/de-DE.js Adds a derived cardinal ceiling (incl. decimal significant digits) and applies tooLargeError guards to cardinal/ordinal/currency entry points.

@TylerVigario TylerVigario merged commit e8c16cf into main Jun 4, 2026
8 checks passed
@TylerVigario TylerVigario deleted the fix/germanic-scale-ceilings branch June 4, 2026 14:06
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.

2 participants