diff options
author | Julian Berman <Julian@GrayVines.com> | 2020-10-04 20:04:22 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-04 20:04:22 -0400 |
commit | e48d56cbd2b6c25d4a9483f53f79ec537b9a4a34 (patch) | |
tree | 455dc97d7269efcbd24c4d831ce5fccaafa34d13 | |
parent | 58259e7a9fc1d8ef0602c06060bba4607c99bd90 (diff) | |
parent | 46db62a373ccc3d75fefd36f97a5fa8fcafedac4 (diff) | |
download | jsonschema-e48d56cbd2b6c25d4a9483f53f79ec537b9a4a34.tar.gz |
Merge pull request #746 from Zac-HD/multipleOf-overflow
Handle `multipleOf` overflow
-rw-r--r-- | jsonschema/_validators.py | 14 | ||||
-rw-r--r-- | jsonschema/tests/test_jsonschema_test_suite.py | 39 |
2 files changed, 13 insertions, 40 deletions
diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index d7097ff..7e8c95a 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -1,3 +1,4 @@ +from fractions import Fraction import re from jsonschema._utils import ( @@ -166,7 +167,18 @@ def multipleOf(validator, dB, instance, schema): if isinstance(dB, float): quotient = instance / dB - failed = int(quotient) != quotient + try: + failed = int(quotient) != quotient + except OverflowError: + # When `instance` is large and `dB` is less than one, quotient can + # overflow to infinity; and then casting to int raises an error. + # + # In this case we fall back to Fraction logic, which is exact and + # cannot overflow. The performance is also acceptable: we try the + # fast all-float option first, and we know that fraction(dB) can have + # at most a few hundred digits in each part. The worst-case slowdown + # is therefore for already-slow enormous integers or Decimals. + failed = (Fraction(instance) / Fraction(dB)).denominator != 1 else: failed = instance % dB diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index d6721b5..0f9698a 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -161,7 +161,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.tests(), DRAFT4.format_tests(), DRAFT4.optional_tests_of(name="bignum"), - DRAFT4.optional_tests_of(name="float-overflow"), DRAFT4.optional_tests_of(name="non-bmp-regex"), DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft4Validator, @@ -235,18 +234,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase( subject="uniqueItems", description='{"a": true} and {"a": 1} are unique', )(test) - or skip( - message=bug(743), - subject="float-overflow", - )(test) - or skip( - message=bug(743), - subject="multipleOf", - description=( - "always invalid, but naive implementations " - "may raise an overflow error" - ), - )(test) ), ) @@ -255,7 +242,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.tests(), DRAFT6.format_tests(), DRAFT6.optional_tests_of(name="bignum"), - DRAFT6.optional_tests_of(name="float-overflow"), DRAFT6.optional_tests_of(name="non-bmp-regex"), Validator=Draft6Validator, format_checker=draft6_format_checker, @@ -348,18 +334,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase( subject="const", case_description='const with {"a": true} does not match {"a": 1}', )(test) - or skip( - message=bug(743), - subject="float-overflow", - )(test) - or skip( - message=bug(743), - subject="multipleOf", - description=( - "always invalid, but naive implementations " - "may raise an overflow error" - ), - )(test) ), ) @@ -368,7 +342,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase( DRAFT7.tests(), DRAFT7.format_tests(), DRAFT7.optional_tests_of(name="bignum"), - DRAFT7.optional_tests_of(name="float-overflow"), DRAFT7.optional_tests_of(name="content"), DRAFT7.optional_tests_of(name="non-bmp-regex"), Validator=Draft7Validator, @@ -484,18 +457,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase( subject="const", case_description='const with {"a": true} does not match {"a": 1}', )(test) - or skip( - message=bug(743), - subject="float-overflow", - )(test) - or skip( - message=bug(743), - subject="multipleOf", - description=( - "always invalid, but naive implementations " - "may raise an overflow error" - ), - )(test) ), ) |