diff --git a/changelog.d/10611.bugfix b/changelog.d/10611.bugfix
new file mode 100644
index 0000000000..ecbe408b47
--- /dev/null
+++ b/changelog.d/10611.bugfix
@@ -0,0 +1 @@
+Additional validation for the spaces summary API to avoid errors like `ValueError: Stop argument for islice() must be None or an integer`. The missing validation has existed since v1.31.0.
diff --git a/synapse/federation/transport/server/federation.py b/synapse/federation/transport/server/federation.py
index 7d81cc642c..2fdf6cc99e 100644
--- a/synapse/federation/transport/server/federation.py
+++ b/synapse/federation/transport/server/federation.py
@@ -557,7 +557,14 @@ class FederationSpaceSummaryServlet(BaseFederationServlet):
room_id: str,
) -> Tuple[int, JsonDict]:
suggested_only = parse_boolean_from_args(query, "suggested_only", default=False)
+
max_rooms_per_space = parse_integer_from_args(query, "max_rooms_per_space")
+ if max_rooms_per_space is not None and max_rooms_per_space < 0:
+ raise SynapseError(
+ 400,
+ "Value for 'max_rooms_per_space' must be a non-negative integer",
+ Codes.BAD_JSON,
+ )
exclude_rooms = parse_strings_from_args(query, "exclude_rooms", default=[])
@@ -586,10 +593,17 @@ class FederationSpaceSummaryServlet(BaseFederationServlet):
raise SynapseError(400, "bad value for 'exclude_rooms'", Codes.BAD_JSON)
max_rooms_per_space = content.get("max_rooms_per_space")
- if max_rooms_per_space is not None and not isinstance(max_rooms_per_space, int):
- raise SynapseError(
- 400, "bad value for 'max_rooms_per_space'", Codes.BAD_JSON
- )
+ if max_rooms_per_space is not None:
+ if not isinstance(max_rooms_per_space, int):
+ raise SynapseError(
+ 400, "bad value for 'max_rooms_per_space'", Codes.BAD_JSON
+ )
+ if max_rooms_per_space < 0:
+ raise SynapseError(
+ 400,
+ "Value for 'max_rooms_per_space' must be a non-negative integer",
+ Codes.BAD_JSON,
+ )
return 200, await self.handler.federation_space_summary(
origin, room_id, suggested_only, max_rooms_per_space, exclude_rooms
diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py
index d3882a84e2..ba7250ad8e 100644
--- a/synapse/rest/client/v1/room.py
+++ b/synapse/rest/client/v1/room.py
@@ -993,11 +993,19 @@ class RoomSpaceSummaryRestServlet(RestServlet):
) -> Tuple[int, JsonDict]:
requester = await self._auth.get_user_by_req(request, allow_guest=True)
+ max_rooms_per_space = parse_integer(request, "max_rooms_per_space")
+ if max_rooms_per_space is not None and max_rooms_per_space < 0:
+ raise SynapseError(
+ 400,
+ "Value for 'max_rooms_per_space' must be a non-negative integer",
+ Codes.BAD_JSON,
+ )
+
return 200, await self._room_summary_handler.get_space_summary(
requester.user.to_string(),
room_id,
suggested_only=parse_boolean(request, "suggested_only", default=False),
- max_rooms_per_space=parse_integer(request, "max_rooms_per_space"),
+ max_rooms_per_space=max_rooms_per_space,
)
# TODO When switching to the stable endpoint, remove the POST handler.
@@ -1014,10 +1022,17 @@ class RoomSpaceSummaryRestServlet(RestServlet):
)
max_rooms_per_space = content.get("max_rooms_per_space")
- if max_rooms_per_space is not None and not isinstance(max_rooms_per_space, int):
- raise SynapseError(
- 400, "'max_rooms_per_space' must be an integer", Codes.BAD_JSON
- )
+ if max_rooms_per_space is not None:
+ if not isinstance(max_rooms_per_space, int):
+ raise SynapseError(
+ 400, "'max_rooms_per_space' must be an integer", Codes.BAD_JSON
+ )
+ if max_rooms_per_space < 0:
+ raise SynapseError(
+ 400,
+ "Value for 'max_rooms_per_space' must be a non-negative integer",
+ Codes.BAD_JSON,
+ )
return 200, await self._room_summary_handler.get_space_summary(
requester.user.to_string(),
|