Skip to content

Commit 12a3e34

Browse files
authored
bpo-31247: xmlrpc.server: break reference cycle (#3166) (#3168)
xmlrpc.server now explicitly breaks reference cycles when using sys.exc_info() in code handling exceptions. (cherry picked from commit 8452445)
1 parent 24c0c5b commit 12a3e34

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

Lib/xmlrpc/server.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,14 @@ def _marshaled_dispatch(self, data, dispatch_method = None, path = None):
264264
except:
265265
# report exception back to server
266266
exc_type, exc_value, exc_tb = sys.exc_info()
267-
response = dumps(
268-
Fault(1, "%s:%s" % (exc_type, exc_value)),
269-
encoding=self.encoding, allow_none=self.allow_none,
270-
)
267+
try:
268+
response = dumps(
269+
Fault(1, "%s:%s" % (exc_type, exc_value)),
270+
encoding=self.encoding, allow_none=self.allow_none,
271+
)
272+
finally:
273+
# Break reference cycle
274+
exc_type = exc_value = exc_tb = None
271275

272276
return response.encode(self.encoding, 'xmlcharrefreplace')
273277

@@ -359,10 +363,14 @@ def system_multicall(self, call_list):
359363
)
360364
except:
361365
exc_type, exc_value, exc_tb = sys.exc_info()
362-
results.append(
363-
{'faultCode' : 1,
364-
'faultString' : "%s:%s" % (exc_type, exc_value)}
365-
)
366+
try:
367+
results.append(
368+
{'faultCode' : 1,
369+
'faultString' : "%s:%s" % (exc_type, exc_value)}
370+
)
371+
finally:
372+
# Break reference cycle
373+
exc_type = exc_value = exc_tb = None
366374
return results
367375

368376
def _dispatch(self, method, params):
@@ -624,10 +632,14 @@ def _marshaled_dispatch(self, data, dispatch_method = None, path = None):
624632
# (each dispatcher should have handled their own
625633
# exceptions)
626634
exc_type, exc_value = sys.exc_info()[:2]
627-
response = dumps(
628-
Fault(1, "%s:%s" % (exc_type, exc_value)),
629-
encoding=self.encoding, allow_none=self.allow_none)
630-
response = response.encode(self.encoding, 'xmlcharrefreplace')
635+
try:
636+
response = dumps(
637+
Fault(1, "%s:%s" % (exc_type, exc_value)),
638+
encoding=self.encoding, allow_none=self.allow_none)
639+
response = response.encode(self.encoding, 'xmlcharrefreplace')
640+
finally:
641+
# Break reference cycle
642+
exc_type = exc_value = None
631643
return response
632644

633645
class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
xmlrpc.server now explicitly breaks reference cycles when using
2+
sys.exc_info() in code handling exceptions.

0 commit comments

Comments
 (0)