#37464 new Bug

StepValueValidator accepts invalid values and crashes on large numbers

Reported by: Akshat Gupta Owned by:
Component: Forms Version: dev
Severity: Normal Keywords: StepValueValidator, step_size, float, OverflowError
Cc: Akshat Gupta Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

StepValueValidator uses math.remainder(). That converts values to float. Large integers and Decimals lose precision or crash.

from decimal import Decimal
from django import forms

forms.IntegerField(step_size=2).clean("9007199254740993")
# Returns 9007199254740993. It is odd, so it should be rejected.

forms.IntegerField(step_size=2).clean("9" * 400)
# OverflowError: int too large to convert to float

forms.DecimalField(step_size=Decimal("0.1")).clean("1e400")
# ValueError: math domain error

forms.DecimalField(step_size=Decimal("0.01")).clean("12345678901234567.01")
# ValidationError, but the value is a valid multiple of 0.01

The first case lets an invalid value through. The next two raise an unhandled exception, so user input can cause a 500 error.

Floats are also used for the tolerance (abs_tol=1e-9). So Decimal("1.00000000005") is accepted with a step of Decimal("1e-10").

I think int and Decimal values should be checked with exact arithmetic. The float path can stay as it is. Be careful not to turn the Decimal into a huge number: Fraction(Decimal("1e50000000")) takes about a minute.

I am happy to work on a patch once this is accepted.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top