diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-08-21 16:12:58 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 16:12:58 (GMT) |
commit | 84524454d0ba77d299741c47bd0f5841ac3f66ce (patch) | |
tree | e6ef68ff4bde65b33d521d7c910524527fd4a6c7 | |
parent | f432a3234f9f2ee09bd40be03e06bf72865ee375 (diff) | |
download | cpython-84524454d0ba77d299741c47bd0f5841ac3f66ce.zip cpython-84524454d0ba77d299741c47bd0f5841ac3f66ce.tar.gz cpython-84524454d0ba77d299741c47bd0f5841ac3f66ce.tar.bz2 |
bpo-31247: xmlrpc.server: break reference cycle (#3166)
xmlrpc.server now explicitly breaks reference cycles when using
sys.exc_info() in code handling exceptions.
-rw-r--r-- | Lib/xmlrpc/server.py | 36 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2017-08-21-17-50-27.bpo-31247.8S3zJp.rst | 2 |
2 files changed, 26 insertions, 12 deletions
diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index bb86fe6..88d0eec 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -270,10 +270,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') @@ -365,10 +369,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): @@ -630,10 +638,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. |