diff --git a/playwright/_impl/_fetch.py b/playwright/_impl/_fetch.py index 094f87297..624d5f1b0 100644 --- a/playwright/_impl/_fetch.py +++ b/playwright/_impl/_fetch.py @@ -645,7 +645,12 @@ def is_json_parsable(value: Any) -> bool: if not isinstance(value, str): return False try: - json.loads(value) + # NaN and Infinity are not valid JSON, unlike what json.loads() accepts by default. + json.loads(value, parse_constant=_reject_json_constant) return True - except json.JSONDecodeError: + except ValueError: return False + + +def _reject_json_constant(value: str) -> Any: + raise ValueError(f"{value} is not valid JSON") diff --git a/tests/async/test_fetch_global.py b/tests/async/test_fetch_global.py index cd4538e51..00d5b50bf 100644 --- a/tests/async/test_fetch_global.py +++ b/tests/async/test_fetch_global.py @@ -391,6 +391,17 @@ async def test_should_json_stringify_string_body_when_content_type_is_applicatio ), ) assert req.post_body == b'"foo"' + # https://github.com/microsoft/playwright/issues/43329 + # NaN is not valid JSON, even though json.loads() accepts it. + [req, _] = await asyncio.gather( + server.wait_for_request("/empty.html"), + request.post( + server.EMPTY_PAGE, + headers={"content-type": "application/json"}, + data="NaN", + ), + ) + assert req.post_body == b'"NaN"' await request.dispose()