FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix SystemError when convert()'ing an out-of-range int to float by STiFLeR7 · Pull Request #1162 · msgspec/msgspec · GitHub

Fix SystemError when convert()'ing an out-of-range int to float - #1162

Open
STiFLeR7 wants to merge 1 commit into
msgspec:mainfrom
STiFLeR7:fix/convert-float-overflow-systemerror
Open

Fix SystemError when convert()'ing an out-of-range int to float#1162
STiFLeR7 wants to merge 1 commit into
msgspec:mainfrom
STiFLeR7:fix/convert-float-overflow-systemerror

Conversation

Copy link
Copy Markdown

Summary

msgspec.convert(obj, float) converts a Python int to a C double via PyLong_AsDouble without checking for overflow. For an int too large to represent as a finite float (e.g. 10**400), PyLong_AsDouble sets OverflowError internally but still returns -1.0, and that value was passed straight through to ms_decode_float and returned to the interpreter with the exception still set — which surfaces as:

SystemError: <built-in function convert> returned a result with an exception set

This bypasses the documented ValidationError contract entirely, so a caller wrapping the call in except msgspec.ValidationError doesn't catch it.

json.decode already handles the equivalent case correctly, raising ValidationError: Number out of range. This PR applies the same "check PyErr_Occurred() after a lossy C conversion, then report via ms_error_with_path" pattern already used elsewhere in this file (e.g. _constr_as_f64), so convert() reports the overflow the same way — for both bare (convert(big, float)) and nested (convert({"x": big}, dict[str, float])) targets, under both strict=True and strict=False.

Fixes #1122.

Testing

  • Reverted the fix locally and reproduced the exact reported SystemError before reapplying it.
  • Added test_float_from_int_out_of_range to TestFloat in tests/unit/test_convert.py, covering bare and nested targets under both strict modes.
  • Ran the full tests/unit/ suite: 6052 passed, 473 skipped, 0 failures.

msgspec.convert(obj, float) converts a python int to a C double via
PyLong_AsDouble without checking for overflow. For an int too large to
represent as a float, PyLong_AsDouble sets OverflowError but still
returns -1.0, and that value was passed straight through to
ms_decode_float and returned to the interpreter with the exception
still set - which surfaces as SystemError: <built-in function convert>
returned a result with an exception set, bypassing the documented
ValidationError contract entirely.

json.decode already handles the equivalent case correctly, raising
ValidationError: Number out of range. Apply the same
value-error-with-path check convert() already uses elsewhere in this
file (e.g. _constr_as_f64) so the overflow is reported the same way,
for both bare and nested (e.g. dict[str, float]) targets, under both
strict and lax mode.

Fixes msgspec#1122.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

convert leaks SystemError on an out-of-range int → float, where json.decode cleanly raises ValidationError

1 participant


Back | FazBrowse Home | New Git URL