1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix non_numeric_string?

For example, dirty checking was not right for the following case:

```
model.int_column = "+5"
model.float_column = "0.5E+1"
model.decimal_column = "0.5e-3"
```

It is enough to see whether leading character is a digit for avoiding
invalid numeric expression like 'wibble' to be type-casted to 0, as
this method's comment says.

Fixes #33801
This commit is contained in:
Yoshiyuki Kinjo 2018-09-06 20:02:12 +09:00
parent 54a9dbf5f1
commit ba406d9c22
4 changed files with 14 additions and 4 deletions

View file

@ -29,7 +29,7 @@ module ActiveModel
# 'wibble'.to_i will give zero, we want to make sure
# that we aren't marking int zero to string zero as
# changed.
value.to_s !~ /\A-?\d+\.?\d*\z/
!/\A[-+]?\d+/.match?(value.to_s)
end
end
end

View file

@ -57,9 +57,12 @@ module ActiveModel
def test_changed?
type = Decimal.new
assert type.changed?(5.0, 5.0, "5.0wibble")
assert type.changed?(0.0, 0, "wibble")
assert type.changed?(5.0, 0, "wibble")
assert_not type.changed?(5.0, 5.0, "5.0wibble")
assert_not type.changed?(5.0, 5.0, "5.0")
assert_not type.changed?(-5.0, -5.0, "-5.0")
assert_not type.changed?(5.0, 5.0, "0.5e+1")
end
def test_scale_is_applied_before_precision_to_prevent_rounding_errors

View file

@ -21,9 +21,12 @@ module ActiveModel
def test_changing_float
type = Type::Float.new
assert type.changed?(5.0, 5.0, "5wibble")
assert type.changed?(0.0, 0, "wibble")
assert type.changed?(5.0, 0, "wibble")
assert_not type.changed?(5.0, 5.0, "5wibble")
assert_not type.changed?(5.0, 5.0, "5")
assert_not type.changed?(5.0, 5.0, "5.0")
assert_not type.changed?(500.0, 500.0, "0.5E+4")
assert_not type.changed?(nil, nil, nil)
end
end

View file

@ -53,9 +53,13 @@ module ActiveModel
test "changed?" do
type = Type::Integer.new
assert type.changed?(5, 5, "5wibble")
assert type.changed?(0, 0, "wibble")
assert type.changed?(5, 0, "wibble")
assert_not type.changed?(5, 5, "5wibble")
assert_not type.changed?(5, 5, "5")
assert_not type.changed?(5, 5, "5.0")
assert_not type.changed?(5, 5, "+5")
assert_not type.changed?(5, 5, "+5.0")
assert_not type.changed?(-5, -5, "-5")
assert_not type.changed?(-5, -5, "-5.0")
assert_not type.changed?(nil, nil, nil)