clonebundle-digest: add recursion guards for Python 3.8
For Python 3.8 and 3.9, the read/readinto pair can recurse, so make sure
the data is only hashed once.
--- a/mercurial/url.py Tue Oct 08 01:06:57 2024 -0400
+++ b/mercurial/url.py Fri Oct 11 14:37:59 2024 +0200
@@ -538,18 +538,27 @@
)
def read(self, amt=None):
+ self._digest_recursion_level += 1
data = super().read(amt)
- self._digest_input(data)
+ self._digest_recursion_level -= 1
+ if self._digest_recursion_level == 0:
+ self._digest_input(data)
return data
def readline(self):
+ self._digest_recursion_level += 1
data = super().readline()
- self._digest_input(data)
+ self._digest_recursion_level -= 1
+ if self._digest_recursion_level == 0:
+ self._digest_input(data)
return data
def readinto(self, dest):
+ self._digest_recursion_level += 1
got = super().readinto(dest)
- self._digest_input(dest[:got])
+ self._digest_recursion_level -= 1
+ if self._digest_recursion_level == 0:
+ self._digest_input(dest[:got])
return got
def _close_conn(self):
@@ -560,6 +569,8 @@
response._digest = self._digest
response._digest_consumed = 0
response._hasher = self._hasher.copy()
+ # Python 3.8 / 3.9 recurses internally between read/readinto.
+ response._digest_recursion_level = 0
response._digest_finished = False
return response