Skip to content

Reject non-finite values (nan, inf) in FloatField - #9998

Merged
auvipy merged 4 commits into
encode:mainfrom
winklemad:fix-floatfield-non-finite
Sep 7, 2026
Merged

auvipy merged 4 commits into
encode:mainfrom
winklemad:fix-floatfield-non-finite

Conversation

@winklemad

Copy link
Copy Markdown
Contributor

Description

FloatField accepts non-finite floats — nan, inf, -inf, and overflow-to-inf strings such as "1e400" — returning float('nan') / float('inf') instead of raising a ValidationError. It is the only DRF numeric field without a finiteness guard: IntegerField and DecimalField already reject these, as does Django's own forms.FloatField.

serializers.FloatField().run_validation('nan')    # -> nan   (before); ValidationError (after)
serializers.FloatField().run_validation('inf')    # -> inf   (before); ValidationError (after)
serializers.FloatField().run_validation('1e400')  # -> inf   (before); ValidationError (after)

The value arrives as a JSON/form string (e.g. "nan"), so it slips past the JSON parser's parse_constant guard — float("nan") accepts it.

Why it matters

REST framework deliberately renders JSON with allow_nan=False to stay spec-compliant (rest_framework/utils/json.py). A non-finite value accepted by FloatField therefore raises ValueError: Out of range float values are not JSON compliant when the object is later serialized, turning a silent validation gap into a 500 error:

from rest_framework.renderers import JSONRenderer
JSONRenderer().render({'x': serializers.FloatField().run_validation('inf')})
# ValueError: Out of range float values are not JSON compliant: inf

Fix

Guard to_internal_value with math.isfinite, mirroring DecimalField (which rejects is_nan) and Django's forms.FloatField (which uses math.isfinite). The existing overflow path (huge integer inputs raising OverflowError) is unchanged; string inputs like "1e400" that float() turns into inf are now rejected as invalid.

Added nan, inf, -inf, 1e400, and native float('nan') / float('inf') cases to TestFloatField.invalid_inputs. Full tests/test_fields.py passes (334 passed, 3 pre-existing skips).

FloatField accepted nan, inf, -inf and overflow-to-inf strings such as
"1e400", returning float('nan')/float('inf') instead of raising a
ValidationError. It was the only numeric field without a finiteness
guard: IntegerField and DecimalField already reject these, as does
Django's own forms.FloatField.

REST framework renders JSON with allow_nan=False to stay spec-compliant,
so a non-finite value accepted here raises "Out of range float values
are not JSON compliant" when the object is later serialized, turning a
validation gap into a 500 error.

Guard to_internal_value with math.isfinite, mirroring DecimalField's
is_nan check and Django's forms.FloatField.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped, uses a well-supported standard-library check, and is backed by targeted test coverage for the newly rejected inputs.

Pull request overview

This PR tightens FloatField input validation to reject non-finite float values (NaN, Infinity, -Infinity, and overflow-to-inf strings like "1e400"), aligning FloatField behavior with DRF’s other numeric fields and avoiding downstream JSON rendering failures when allow_nan=False.

Changes:

  • Add a finiteness guard (math.isfinite) in FloatField.to_internal_value to treat non-finite results as invalid.
  • Extend TestFloatField.invalid_inputs coverage to include string and native-float non-finite cases.
File summaries
File Description
rest_framework/fields.py Rejects non-finite float values during FloatField validation via math.isfinite.
tests/test_fields.py Adds regression tests asserting FloatField rejects nan/inf/-inf/1e400 and native non-finite floats.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@auvipy auvipy added this to the 3.18 milestone Sep 6, 2026
@auvipy
auvipy self-requested a review September 6, 2026 17:38

@browniebroke browniebroke left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change looks good, thanks.

It is the only DRF numeric field without a finiteness guard: IntegerField and DecimalField already reject these, as does Django's own forms.FloatField.

I noticed that the TestDecimalField is explicitly testing for this, but TestIntegerField isn't... I've just expanded the existing tests to cover for this.

@auvipy
auvipy merged commit 858f1fc into encode:main Sep 7, 2026
7 checks passed
@winklemad

Copy link
Copy Markdown
Contributor Author

Thanks @browniebroke — nice, good call expanding the TestIntegerField coverage to match; glad this closes the gap.

HosseinSayyedMousavi pushed a commit to HosseinSayyedMousavi/django-rest-framework that referenced this pull request Oct 8, 2026
* Reject non-finite values in FloatField.to_internal_value

FloatField accepted nan, inf, -inf and overflow-to-inf strings such as
"1e400", returning float('nan')/float('inf') instead of raising a
ValidationError. It was the only numeric field without a finiteness
guard: IntegerField and DecimalField already reject these, as does
Django's own forms.FloatField.

REST framework renders JSON with allow_nan=False to stay spec-compliant,
so a non-finite value accepted here raises "Out of range float values
are not JSON compliant" when the object is later serialized, turning a
validation gap into a 500 error.

Guard to_internal_value with math.isfinite, mirroring DecimalField's
is_nan check and Django's forms.FloatField.

* Expand IntegerField tests to explicitly test for 'inf' and 'nan' as invalid

---------

Co-authored-by: Asif Saif Uddin {"Auvi":"অভি"} <[email protected]>
Co-authored-by: Bruno Alla <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants