Skip to content

Report oversized regex repeat count as invalid instead of crashing#1526

Open
vineethsaivs wants to merge 1 commit into
python-jsonschema:mainfrom
vineethsaivs:fix/regex-format-overflow
Open

Report oversized regex repeat count as invalid instead of crashing#1526
vineethsaivs wants to merge 1 commit into
python-jsonschema:mainfrom
vineethsaivs:fix/regex-format-overflow

Conversation

@vineethsaivs

Copy link
Copy Markdown

The regex format checker is declared with raises=re.error:

@_checks_drafts(name="regex", raises=re.error)
def is_regex(instance: object) -> bool:
    if not isinstance(instance, str):
        return True
    return bool(re.compile(instance))

FormatChecker.check only converts the declared exception(s) into a FormatError. But re.compile raises OverflowError (which is not an re.error subclass) when a repetition count is too large, e.g. re.compile("a{99999999999999}"). That OverflowError escapes uncaught, so a regex-format check on such a string crashes instead of reporting it as an invalid regex, unlike every other malformed pattern (which raises re.error and is caught).

>>> from jsonschema import FormatChecker
>>> fc = FormatChecker()
>>> fc.conforms("[unterminated", "regex")   # re.error -> caught
False
>>> fc.conforms("a{99999999999999}", "regex")   # OverflowError -> escapes
Traceback (most recent call last):
  ...
OverflowError: the repetition number is too large

The same escape happens through iter_errors/validate when format checking is enabled.

Fix

Declare the checker with raises=(re.error, OverflowError) so the oversized-repeat case is reported as an invalid regex like the rest. This matches sibling checkers that already pass exception tuples (e.g. raises=(idna.IDNAError, UnicodeError)). No behavior change for valid patterns or for re.error cases.

Tests

Added TestFormatChecker.test_regex_format_rejects_overflowing_repeat_count, mirroring the existing test_format_checkers_come_with_defaults (uses checker.check(...) + assertRaises(FormatError)).

  • Before: the new test errors with an uncaught OverflowError.
  • After: it passes; conforms("a{99999999999999}", "regex") returns False, while conforms("[unterminated", "regex") stays False and conforms("valid.*regex", "regex") stays True.
  • python -m pytest jsonschema/tests/test_format.py -> 9 passed.

Added a CHANGELOG entry.

The "regex" format checker declared raises=re.error, but re.compile
raises OverflowError (not an re.error subclass) when a repetition count
is too large, e.g. "a{99999999999999}". That OverflowError escaped
FormatChecker.check uncaught, crashing conforms()/iter_errors()/validate
instead of reporting the string as an invalid regex, unlike every other
malformed pattern which is caught via re.error.

Declare raises=(re.error, OverflowError) so the oversized-repeat case is
reported as an invalid regex like the rest. Add a regression test.
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 python-jsonschema | 🛠️ Build #33655353 | 📁 Comparing 19e96d3 against latest (0274292)

  🔍 Preview build  

1 file changed
± _modules/jsonschema/_format/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant