Skip to content

Reject unexpected spellings of NaN and Infinity in Python JSON parsing - #30443

Open
ManoharPaturi wants to merge 1 commit into
protocolbuffers:mainfrom
ManoharPaturi:fix-json-float-spellings
Open

ManoharPaturi wants to merge 1 commit into
protocolbuffers:mainfrom
ManoharPaturi:fix-json-float-spellings

Conversation

@ManoharPaturi

Copy link
Copy Markdown

The proto3 JSON mapping allows exactly three spellings for non finite float values: "NaN", "Infinity" and "-Infinity". The pure Python json_format delegated quoted values to float(), which accepts a much wider family of spellings, so inputs like "NAN", "+nan", "inf", "INF", "+Infinity" or " NaN " were silently accepted here while every other implementation rejects them. A backend that validates JSON in Python therefore accepts payloads that a C++, Java or upb frontend would refuse, which is a quiet validation gap rather than a crash.

This adds an explicit check in _ConvertFloat: when the stripped and lowercased value is one of the nan or inf word family, it must be exactly one of the three canonical spellings, otherwise ParseError is raised. Unquoted JSON numbers are unaffected because they arrive as float instances, and the float and double paths share this function, so both are covered.

Behavior before the change, observed with the pure Python implementation:

json_format.Parse('{"floatValue": "NAN"}', msg)     -> accepted, msg.float_value = nan
json_format.Parse('{"floatValue": "+Infinity"}', msg) -> accepted, msg.float_value = inf
json_format.Parse('{"floatValue": " NaN "}', msg)   -> accepted, msg.float_value = nan

After the change all three raise ParseError, while "NaN", "Infinity" and "-Infinity" continue to round trip through MessageToJson and Parse.

Testing: extended testInvalidFloatValue in python/google/protobuf/internal/json_format_test.py with fourteen rejected spellings and updated the expectation for "nan", whose message now names all three canonical forms. The full json_format_test.py suite passes under PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (112 tests locally).

Python's float() accepts many spellings of NaN and Infinity beyond the
three canonical ones the proto3 JSON mapping allows, so the pure Python
json_format silently accepted inputs like "NAN", "+nan", "inf",
"INF", "+Infinity" or " NaN " that every other implementation
rejects.  Reject them so a Python backend can not be fed values that
would fail to parse elsewhere.
@ManoharPaturi
ManoharPaturi requested a review from a team as a code owner October 4, 2026 02:58
@ManoharPaturi
ManoharPaturi requested review from anandolee and removed request for a team October 4, 2026 02:58

This branch has not been deployed

No deployments
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