Skip to content

Commit 1d056e2

Browse files
author
Bart de Water
committed
Tighten allowed notation for Simple parser
1 parent e9f4588 commit 1d056e2

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

lib/money/parser/simple.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
class Money
33
module Parser
44
class Simple
5+
SIGNED_DECIMAL_MATCHER = /\A-?\d*(?:\.\d*)?\z/.freeze
6+
57
class << self
68
# Parses an input string using BigDecimal, it always expects a dot character as a decimal separator and
79
# generally does not accept other characters other than minus-hyphen and digits. It is useful for APIs, interop
@@ -15,8 +17,8 @@ def parse(input, currency, strict: false)
1517
currency = Money::Helpers.value_to_currency(currency)
1618
return unless currency
1719

18-
amount = BigDecimal(input, exception: false)
19-
if amount
20+
coerced = input.to_s
21+
if SIGNED_DECIMAL_MATCHER.match?(coerced) && (amount = BigDecimal(coerced, exception: false))
2022
Money.new(amount, currency)
2123
elsif strict
2224
raise ArgumentError, "unable to parse input=\"#{input}\" currency=\"#{currency}\""

spec/parser/simple_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
it "parses an invalid string when not strict" do
1111
expect(described_class.parse("no money", "CAD")).to be_nil
1212
expect(described_class.parse("1..", "CAD")).to be_nil
13+
expect(described_class.parse("10.", "CAD")).to be_nil
14+
expect(described_class.parse("10.1E2", "CAD")).to be_nil
1315
end
1416

1517
it "raises with an invalid string and strict option" do
1618
expect { described_class.parse("no money", "CAD", strict: true) }.to raise_error(ArgumentError)
1719
expect { described_class.parse("1..1", "CAD", strict: true) }.to raise_error(ArgumentError)
20+
expect { described_class.parse("10.", "CAD", strict: true) }.to raise_error(ArgumentError)
21+
expect { described_class.parse("10.1E2", "CAD", strict: true) }.to raise_error(ArgumentError)
1822
end
1923

2024
it "parses an integer string amount" do
@@ -36,12 +40,14 @@
3640
expect(described_class.parse("$1.37", "CAD")).to be_nil
3741
expect(described_class.parse(",1.37", "CAD")).to be_nil
3842
expect(described_class.parse("€1.37", "CAD")).to be_nil
43+
expect(described_class.parse(" 1.37", "CAD")).to be_nil
3944
end
4045

4146
it "does not parse a float string amount with a trailing random character" do
4247
expect(described_class.parse("1.37$", "CAD")).to be_nil
4348
expect(described_class.parse("1.37,", "CAD")).to be_nil
4449
expect(described_class.parse("1.37€", "CAD")).to be_nil
50+
expect(described_class.parse("1.37 ", "CAD")).to be_nil
4551
end
4652

4753
it "does not parse an amount with one or more thousands separators" do

0 commit comments

Comments
 (0)