Skip to content

Update to Decimal 3.0, update dependencies, fix Elixir 1.19 warnings#67

Open
jeremyowensboggs wants to merge 2 commits into
danielberkompas:masterfrom
jeremyowensboggs:update-decimal-fix-elixir-1.19-warnings
Open

Update to Decimal 3.0, update dependencies, fix Elixir 1.19 warnings#67
jeremyowensboggs wants to merge 2 commits into
danielberkompas:masterfrom
jeremyowensboggs:update-decimal-fix-elixir-1.19-warnings

Conversation

@jeremyowensboggs
Copy link
Copy Markdown

@jeremyowensboggs jeremyowensboggs commented May 8, 2026

  • Update decimal dependency to ~> 3.0 (no longer backward compat, see below)
  • Update other dependencies in mix.lock
  • Move preferred_cli_env to def cli (deprecated in Mix 1.19)
  • Replace single-quoted charlists with ~c sigil in doctests
  • Fix compile-time type checker warning in conversion test

Problem

Decimal 3.x made Decimal.new/1 strict about the number of significant digits it accepts (default max: 28). This causes Number.Delimit.number_to_delimited/2 and Number.Currency.number_to_currency/2 to crash with Decimal.Error when given float-derived strings with more than 28 significant digits (e.g. "0.02053473047423571351409743977530517" — 35 digits, typical of IEEE 754 double-precision float-to-string conversion).

The crash path: number_to_delimited converts a non-integer input to a string via to_string/1, then passes it through Number.Conversion.to_decimal/1, which calls Decimal.new/1 on the raw string.

Fix

Replace Decimal.new(string) with Decimal.parse(string, max_digits: 100) in the BitString implementation of Number.Conversion.to_decimal/1. This is the single chokepoint where arbitrary strings become Decimals in the library. 100 digits provides generous headroom beyond any realistic float-derived input while still bounding the parse.

Since Decimal.parse/2 with the max_digits option is a 3.x-only API, this also narrows the decimal dependency to ~> 3.0. If backwards compatibility with decimal 1.x/2.x is desired, a compile-time check for function_exported?(Decimal, :parse, 2) could be added — happy to make that change if needed.

- Update decimal dependency to ~> 3.0 (with backwards compat for ~> 1.5 and ~> 2.0)
- Update other dependencies in mix.lock
- Move preferred_cli_env to def cli (deprecated in Mix 1.19)
- Replace single-quoted charlists with ~c sigil in doctests
- Fix compile-time type checker warning in conversion test
@pwcsquared
Copy link
Copy Markdown

pwcsquared commented May 12, 2026

@danielberkompas There is a moderate vulnerability in the :decimal package fixed in v3.0, so this PR is fairly important to us!

Decimal.new/1 in 3.x rejects strings exceeding the default max_digits
(28). Use Decimal.parse/2 with max_digits: 100 in the BitString
implementation of Number.Conversion.to_decimal/1.

Also narrows the decimal dep spec to ~> 3.0 since parse/2 with
max_digits is a 3.x-only API.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@jeremyowensboggs
Copy link
Copy Markdown
Author

Problem

Decimal 3.x made Decimal.new/1 strict about the number of significant digits it accepts (default max: 28). This causes Number.Delimit.number_to_delimited/2 and Number.Currency.number_to_currency/2 to crash with Decimal.Error when given float-derived strings with more than 28 significant digits (e.g. "0.02053473047423571351409743977530517" — 35 digits, typical of IEEE 754 double-precision float-to-string conversion).

The crash path: number_to_delimited converts a non-integer input to a string via to_string/1, then passes it through Number.Conversion.to_decimal/1, which calls Decimal.new/1 on the raw string.

Fix

Replace Decimal.new(string) with Decimal.parse(string, max_digits: 100) in the BitString implementation of Number.Conversion.to_decimal/1. This is the single chokepoint where arbitrary strings become Decimals in the library. 100 digits provides generous headroom beyond any realistic float-derived input while still bounding the parse.

Since Decimal.parse/2 with the max_digits option is a 3.x-only API, this also narrows the decimal dependency to ~> 3.0. If backwards compatibility with decimal 1.x/2.x is desired, a compile-time check for function_exported?(Decimal, :parse, 2) could be added — happy to make that change if needed.

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