fix: reject NaN in numeric comparison keywords (minimum, maximum, exclusiveMinimum, exclusiveMaximum)#1506
Open
gaoflow wants to merge 2 commits into
Open
fix: reject NaN in numeric comparison keywords (minimum, maximum, exclusiveMinimum, exclusiveMaximum)#1506gaoflow wants to merge 2 commits into
gaoflow wants to merge 2 commits into
Conversation
…lusiveMinimum, exclusiveMaximum)
NaN (float('nan')) previously passed all numeric comparison checks
because Python's NaN comparisons always return False:
instance < minimum -> False (no error, should fail)
instance > maximum -> False (no error, should fail)
instance <= minimum -> False (no error, should fail)
instance >= maximum -> False (no error, should fail)
This allowed NaN-infested schemas to pass check_schema (e.g.
multipleOf=NaN, since the exclusiveMinimum:0 in the meta-schema
did not reject NaN). validate() then crashed with ValueError
inside the multipleOf handler when it tried int(quotient) on NaN.
Invert the comparisons to use the positive form:
not (instance > minimum) for exclusiveMinimum
not (instance < maximum) for exclusiveMaximum
not (instance >= minimum) for minimum
not (instance <= maximum) for maximum
For non-NaN numbers the result is identical. For NaN, all four
positive forms return False, so 'not' yields True (correctly
rejecting NaN).
Also fix the legacy draft3/draft4 equivalents in _legacy_keywords.py.
for more information, see https://pre-commit.ci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NaN (
float("nan")) currently passes all numeric comparison checks because Python's NaN comparisons always returnFalse. This has two consequences:Schema validation bypass:
check_schemadoes not reject schemas containing NaN in numeric fields. For example,{"multipleOf": float("nan")}passes schema validation because the meta-schema'sexclusiveMinimum: 0fails to reject NaN (NaN <= 0isFalse). This then causesvalidate()to crash withValueError: cannot convert float NaN to integerinside themultipleOfhandler.Instance validation bypass: Instances containing NaN pass any
minimum/maximum/exclusiveMinimum/exclusiveMaximumconstraint, even though NaN is not a valid JSON number and cannot satisfy any ordering relationship.The fix inverts the comparison logic to use the positive (non-negated) form:
not (instance > minimum)instead ofinstance <= minimumnot (instance < maximum)instead ofinstance >= maximumnot (instance >= minimum)instead ofinstance < minimumnot (instance <= maximum)instead ofinstance > maximumFor normal numbers the result is identical. For NaN, all four positive comparisons return
False, so the negation correctly yieldsTrue(rejecting NaN). The same fix is applied to the legacy draft3/draft4 equivalents in_legacy_keywords.py.