Skip to content

is_duration raises an uncaught decimal.Overflow on a duration with a large exponent #1511

Description

@vtushar06

The duration format check can raise decimal.Overflow instead of returning a result, so validating certain strings throws an uncaught exception rather than reporting the instance as invalid.

Versions

  • jsonschema 4.25.1
  • isoduration 20.11.0 (the optional dependency is_duration delegates to)
  • Python 3.9

Reproduction

from jsonschema import Draft202012Validator as V
from jsonschema import FormatChecker

v = V({"format": "duration"}, format_checker=FormatChecker())
list(v.iter_errors("P1E1000000D"))

raises:

decimal.Overflow: [<class 'decimal.Overflow'>]

Cause

_format.is_duration calls isoduration.parse_duration(instance) and is registered with raises=isoduration.DurationParsingException. isoduration parses each component amount with Decimal(...), and for an exponent past the decimal context's Emax (999999), Decimal("1E1000000") raises decimal.Overflow. That is not a subclass of DurationParsingException, so it propagates out of the format checker uncaught.

The boundary is exact: P1E999999D is accepted, P1E1000000D overflows. It is also reachable without an exponent, via a plain digit run longer than Emax.

Expected

The check should report the instance as invalid (P1E1000000D is not a valid RFC 3339 Appendix A duration - the grammar uses 1*DIGIT, with no exponent), not raise.

Possible fix

Either broaden what is_duration catches (add ArithmeticError / decimal.Overflow alongside DurationParsingException, or wrap the parse_duration call), or treat any exception from parse_duration as "not a duration".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions