Commits

Anonymous committed 48ecd02

[svn r13193] XmlRpcPlugin: Fixed 'maximum recursion depth exceeded' error on `search.performSearch` with JSON-RPC. Closes #10786.

Comments (0)

Files changed (4)

trunk/tracrpc/json_rpc.py

 import re
 from types import GeneratorType
 
+try:
+    import babel
+except ImportError:
+    babel = None
+import genshi
+
 from trac.core import *
 from trac.perm import PermissionError
 from trac.resource import ResourceNotFound
         """ Extending the JSON encoder to support some additional types:
         1. datetime.datetime => {'__jsonclass__': ["datetime", "<rfc3339str>"]}
         2. tracrpc.api.Binary => {'__jsonclass__': ["binary", "<base64str>"]}
-        3. empty => '' """
+        3. empty => ''
+        4. genshi.builder.Fragment|genshi.core.Markup => unicode
+        5. babel.support.LazyProxy => unicode
+        """
 
         def default(self, obj):
             if isinstance(obj, datetime.datetime):
                                 obj.data.encode("base64")]}
             elif obj is empty:
                 return ''
+            elif isinstance(obj, (genshi.builder.Fragment,
+                                  genshi.core.Markup)):
+                return unicode(obj)
+            elif babel and isinstance(obj, babel.support.LazyProxy):
+                return unicode(obj)
             else:
                 return json.JSONEncoder(self, obj)
 

trunk/tracrpc/tests/__init__.py

         suite.addTest(tracrpc.tests.wiki.test_suite())
         import tracrpc.tests.web_ui
         suite.addTest(tracrpc.tests.web_ui.test_suite())
+        import tracrpc.tests.search
+        suite.addTest(tracrpc.tests.search.test_suite())
         return suite
 
 except Exception, e:

trunk/tracrpc/tests/json_rpc.py

                     result['result']['__jsonclass__'][1].decode("base64"))
             self.assertEquals(image_in.getvalue(), image_out.getvalue())
 
+        def test_fragment(self):
+            data = {'method': 'ticket.create',
+                    'params': ['ticket10786', '',
+                               {'type': 'enhancement', 'owner': 'A'}]}
+            result = self._auth_req(data, user='admin')
+            self.assertEquals(None, result['error'])
+            tktid = result['result']
+
+            data = {'method': 'search.performSearch',
+                    'params': ['ticket10786']}
+            result = self._auth_req(data, user='admin')
+            self.assertEquals(None, result['error'])
+            self.assertEquals('<span class="new">#%d</span>: enhancement: '
+                              'ticket10786 (new)' % tktid,
+                              result['result'][0][1])
+            self.assertEquals(1, len(result['result']))
+
+            data = {'method': 'ticket.delete', 'params': [tktid]}
+            result = self._auth_req(data, user='admin')
+            self.assertEquals(None, result['error'])
+
         def test_xmlrpc_permission(self):
             # Test returned response if not XML_RPC permission
             rpc_testenv._tracadmin('permission', 'remove', 'anonymous',

trunk/tracrpc/xml_rpc.py

 import time
 import xmlrpclib
 
+try:
+    import babel
+except ImportError:
+    babel = None
 import genshi
 
 from trac.core import *
             elif isinstance(res, (genshi.builder.Fragment, \
                                   genshi.core.Markup)):
                 new_result.append(to_unicode(res))
+            elif babel and isinstance(res, babel.support.LazyProxy):
+                new_result.append(to_unicode(res))
             elif isinstance(res, dict):
                 for key, val in res.items():
                     res[key], = self._normalize_xml_output([val])