diff --git a/jmespath/functions.py b/jmespath/functions.py index 627b569d..15a7eee6 100644 --- a/jmespath/functions.py +++ b/jmespath/functions.py @@ -206,7 +206,8 @@ def _func_to_number(self, arg): return int(arg) except ValueError: try: - return float(arg) + number = float(arg) + return number if math.isfinite(number) else None except ValueError: return None diff --git a/tests/test_functions.py b/tests/test_functions.py index a352d69e..58dcb335 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -9,6 +9,18 @@ class TestFunctions(unittest.TestCase): + def test_to_number_rejects_nonfinite_strings(self): + for value in ('NaN', 'nan', 'Infinity', '-Infinity', 'inf', '-inf', + '1e999', '-1e999'): + with self.subTest(value=value): + result = jmespath.search('to_number(@)', value) + self.assertIsNone(result) + self.assertEqual(json.dumps(result, allow_nan=False), 'null') + + def test_to_number_projection_filters_nonfinite_results(self): + values = ['1e2', 'NaN', '-Infinity', '1e999', '-0.5', 'not a number'] + self.assertEqual(jmespath.search('[].to_number(@)', values), [100.0, -0.5]) + def test_can_max_datetimes(self): # This is python specific behavior, but JMESPath does not specify what # you should do with language specific types. We're going to add the