From 12a3e343e1667f91c0095a9a7dc15048cb620e41 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 21 Aug 2017 18:35:04 +0200 Subject: 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 84524454d0ba77d299741c47bd0f5841ac3f66ce) --- Lib/xmlrpc/server.py | 36 ++++++++++++++-------- .../2017-08-21-17-50-27.bpo-31247.8S3zJp.rst | 2 ++ 2 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-08-21-17-50-27.bpo-31247.8S3zJp.rst diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index 6faa2d6..3e0dca0 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -264,10 +264,14 @@ class SimpleXMLRPCDispatcher: except: # report exception back to server exc_type, exc_value, exc_tb = sys.exc_info() - response = dumps( - Fault(1, "%s:%s" % (exc_type, exc_value)), - encoding=self.encoding, allow_none=self.allow_none, - ) + try: + response = dumps( + Fault(1, "%s:%s" % (exc_type, exc_value)), + encoding=self.encoding, allow_none=self.allow_none, + ) + finally: + # Break reference cycle + exc_type = exc_value = exc_tb = None return response.encode(self.encoding, 'xmlcharrefreplace') @@ -359,10 +363,14 @@ class SimpleXMLRPCDispatcher: ) except: exc_type, exc_value, exc_tb = sys.exc_info() - results.append( - {'faultCode' : 1, - 'faultString' : "%s:%s" % (exc_type, exc_value)} - ) + try: + results.append( + {'faultCode' : 1, + 'faultString' : "%s:%s" % (exc_type, exc_value)} + ) + finally: + # Break reference cycle + exc_type = exc_value = exc_tb = None return results def _dispatch(self, method, params): @@ -624,10 +632,14 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer): # (each dispatcher should have handled their own # exceptions) exc_type, exc_value = sys.exc_info()[:2] - response = dumps( - Fault(1, "%s:%s" % (exc_type, exc_value)), - encoding=self.encoding, allow_none=self.allow_none) - response = response.encode(self.encoding, 'xmlcharrefreplace') + try: + response = dumps( + Fault(1, "%s:%s" % (exc_type, exc_value)), + encoding=self.encoding, allow_none=self.allow_none) + response = response.encode(self.encoding, 'xmlcharrefreplace') + finally: + # Break reference cycle + exc_type = exc_value = None return response class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): diff --git a/Misc/NEWS.d/next/Library/2017-08-21-17-50-27.bpo-31247.8S3zJp.rst b/Misc/NEWS.d/next/Library/2017-08-21-17-50-27.bpo-31247.8S3zJp.rst new file mode 100644 index 0000000..6879384 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-08-21-17-50-27.bpo-31247.8S3zJp.rst @@ -0,0 +1,2 @@ +xmlrpc.server now explicitly breaks reference cycles when using +sys.exc_info() in code handling exceptions. -- cgit v0.12