# HG changeset patch # User Goffi # Date 1647964605 -3600 # Node ID 1702b8c821c4c448491c7babdd23ec0a571ebb6b # Parent 3a34d78f2717c9069a1919e4f319cc3b87c97de2 pages (blog/view): avoid infinite recursion when comment nodes are making a loop diff -r 3a34d78f2717 -r 1702b8c821c4 libervia/pages/blog/view/page_meta.py --- a/libervia/pages/blog/view/page_meta.py Wed Jan 26 17:15:36 2022 +0100 +++ b/libervia/pages/blog/view/page_meta.py Tue Mar 22 16:56:45 2022 +0100 @@ -1,17 +1,19 @@ #!/usr/bin/env python3 import html -from typing import Dict, Any -from libervia.server.constants import Const as C -from twisted.words.protocols.jabber import jid -from twisted.web import server -from sat.core.i18n import _, D_ -from sat.tools.common.template import safe +from typing import Any, Dict, Optional + +from sat.core.i18n import D_, _ +from sat.core.log import getLogger from sat.tools.common import uri from sat.tools.common import data_format from sat.tools.common import regex -from sat.core.log import getLogger +from sat.tools.common.template import safe +from twisted.web import server +from twisted.words.protocols.jabber import jid + from libervia.server import utils +from libervia.server.constants import Const as C from libervia.server.utils import SubPage log = getLogger(__name__) @@ -116,7 +118,21 @@ }) -async def appendComments(self, request, blog_items, profile): +async def appendComments( + self, + request: server.Request, + blog_items: dict, + profile: str, + _seen: Optional[set] = None +) -> None: + """Recursively download and append comments of items + + @param blog_items: items data + @param profile: Libervia profile + @param _seen: used to avoid infinite recursion. For internal use only + """ + if _seen is None: + _seen = set() await self.fillMissingIdentities( request, [i['author_jid'] for i in blog_items['items']]) extra: Dict[str, Any] = {C.KEY_ORDER_BY: C.ORDER_BY_CREATION} @@ -126,6 +142,16 @@ for comment_data in blog_item['comments']: service = comment_data['service'] node = comment_data['node'] + service_node = (service, node) + if service_node in _seen: + log.warning( + f"Items from {node!r} at {service} have already been retrieved, " + "there is a recursion at this service" + ) + comment_data["items"] = [] + continue + else: + _seen.add(service_node) try: comments_data = await self.host.bridgeCall('mbGet', service, @@ -146,8 +172,12 @@ continue comments = data_format.deserialise(comments_data) + if comments is None: + log.error(f"Comments should not be None: {comment_data}") + comment_data["items"] = [] + continue comment_data['items'] = comments['items'] - await appendComments(self, request, comments, profile) + await appendComments(self, request, comments, profile, _seen=_seen) async def getBlogItems( self,