--- a/mercurial/bundlecaches.py Thu Oct 03 14:45:01 2024 +0200
+++ b/mercurial/bundlecaches.py Thu Jun 27 03:32:52 2024 +0200
@@ -6,6 +6,7 @@
from __future__ import annotations
import collections
+import re
import typing
from typing import (
@@ -27,6 +28,7 @@
error,
requirements as requirementsmod,
sslutil,
+ url as urlmod,
util,
)
from .utils import stringutil
@@ -406,6 +408,9 @@
return False
+digest_regex = re.compile(b'^[a-z0-9]+:[0-9a-f]+(,[a-z0-9]+:[0-9a-f]+)*$')
+
+
def filterclonebundleentries(
repo, entries, streamclonerequested=False, pullbundles=False
):
@@ -481,6 +486,43 @@
)
continue
+ if b'DIGEST' in entry:
+ if not digest_regex.match(entry[b'DIGEST']):
+ repo.ui.debug(
+ b'filtering %s due to a bad DIGEST attribute\n' % url
+ )
+ continue
+ supported = 0
+ seen = {}
+ for digest_entry in entry[b'DIGEST'].split(b','):
+ algo, digest = digest_entry.split(b':')
+ if algo not in seen:
+ seen[algo] = digest
+ elif seen[algo] != digest:
+ repo.ui.debug(
+ b'filtering %s due to conflicting %s digests\n'
+ % (url, algo)
+ )
+ supported = 0
+ break
+ digester = urlmod.digesthandler.digest_algorithms.get(algo)
+ if digester is None:
+ continue
+ if len(digest) != digester().digest_size * 2:
+ repo.ui.debug(
+ b'filtering %s due to a bad %s digest\n' % (url, algo)
+ )
+ supported = 0
+ break
+ supported += 1
+ else:
+ if supported == 0:
+ repo.ui.debug(
+ b'filtering %s due to lack of supported digest\n' % url
+ )
+ if supported == 0:
+ continue
+
newentries.append(entry)
return newentries