Files
synapse/tests/events/test_event_parsing.py
Erik JohnstonandGitHub e8e5a42180 Fix parsing events that have large integers (#19819)
Follow on from https://github.com/element-hq/synapse/pull/19701.

Unfortunately serde has a bug when using `#[serde(flatten)]` with
`arbitrary-precision` feature when handling integers that fit in a i128
when doing `serde_json::from_value`. See
https://github.com/serde-rs/serde/issues/2230.

The `depythonize` hits the same issue. To fix this we make it so we only
parse events from strings and not values.
2026-06-03 14:52:05 +01:00

103 lines
3.2 KiB
Python

#
# This file is licensed under the Affero General Public License (AGPL) version 3.
#
# Copyright (C) 2026 Element Creations Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# See the GNU Affero General Public License for more details:
# <https://www.gnu.org/licenses/agpl-3.0.html>.
from typing import Any
from parameterized import parameterized_class
from synapse.api.room_versions import RoomVersions
from synapse.events import make_event_from_dict
from synapse.synapse_rust.events import redact_event
from synapse.types import JsonDict
from tests.test_utils.event_injection import EventTypes
from tests.unittest import TestCase
def create_minimal_event_dict(**fields: Any) -> JsonDict:
"""Create a minimal event dict that will parse correctly."""
return {
"type": EventTypes.Message,
"content": {},
"room_id": "!room:id",
"sender": "@user:id",
"event_id": "$event:id",
"origin_server_ts": 0,
"auth_events": [],
"prev_events": [],
"hashes": {},
"signatures": {},
"depth": 0,
**fields,
}
@parameterized_class(
[
{"test_int": 2**7 - 1},
{"test_int": 2**15 - 1},
{"test_int": 2**31 - 1},
{"test_int": 2**63 - 1},
{"test_int": 2**127 - 1},
{"test_int": 2**200},
]
)
class LargeIntTestCase(TestCase):
"""Test that we can handle various sized integers in events.
This is a regression test where we had issues handling integers that fit in
a Rust `i128`.
"""
test_int: int
"""The integer to test with. This will be set by the parameterized_class decorator."""
def test_very_large_int_in_event_content(self) -> None:
"""Test that we can handle integers in the event content, which is a
JsonObject and thus can contain arbitrary JSON."""
event_dict = create_minimal_event_dict(content={"some_field": self.test_int})
event = make_event_from_dict(event_dict, RoomVersions.V1)
self.assertEqual(event.content["some_field"], self.test_int)
def test_large_int_in_unsigned(self) -> None:
"""Test that we can handle integers in the unsigned data, which is an
Unsigned and thus can contain arbitrary JSON."""
event_dict = create_minimal_event_dict(
unsigned={"prev_content": {"some_field": self.test_int}}
)
event = make_event_from_dict(event_dict, RoomVersions.V1)
self.assertEqual(event.unsigned["prev_content"]["some_field"], self.test_int)
def test_large_int_redacted(self) -> None:
"""Test that redact events that have an unsigned field with a large
integer in a protected field"""
event_dict = create_minimal_event_dict(
type=EventTypes.PowerLevels,
state_key="",
content={"users": {"@user:id": self.test_int}},
)
event = make_event_from_dict(event_dict, RoomVersions.V1)
redacted_event = redact_event(event)
self.assertEqual(redacted_event.content["users"]["@user:id"], self.test_int)