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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions