# HG changeset patch # User Anton Shestakov # Date 1618314363 -28800 # Node ID bdda94ea21957ebe046e0b5720aa787629adc035 # Parent d6fa75241975ac42e60005e3c3df0ea6f1c75999 evolve: check stablesortcache index size before unpacking (issue6354) diff -r d6fa75241975 -r bdda94ea2195 hgext3rd/evolve/stablesort.py --- a/hgext3rd/evolve/stablesort.py Tue Apr 13 18:40:19 2021 +0800 +++ b/hgext3rd/evolve/stablesort.py Tue Apr 13 19:46:03 2021 +0800 @@ -905,7 +905,7 @@ indexsizedata = data[offset:offset + S_INDEXSIZE.size] indexsize = S_INDEXSIZE.unpack(indexsizedata)[0] offset += S_INDEXSIZE.size - if len(data) - offset >= indexsize: + if indexsize % self._datastruct.size == 0 and len(data) - offset >= indexsize: index = list(self._deserializedata(data[offset:offset + indexsize])) offset += indexsize expected = index[-1] * self._datastruct.size * 3 diff -r d6fa75241975 -r bdda94ea2195 tests/test-cache-corruption.t --- a/tests/test-cache-corruption.t Tue Apr 13 18:40:19 2021 +0800 +++ b/tests/test-cache-corruption.t Tue Apr 13 19:46:03 2021 +0800 @@ -19,15 +19,21 @@ > # imitating array.array().tobytes() with a platform-dependent item size > sixtyfour = struct.Struct(' thirtytwo = struct.Struct(' iss = struct.Struct(' data = [] > with open(sys.argv[1], 'rb') as f: > header = f.read(24) + > if '--index' in sys.argv: + > indexsize = iss.unpack(f.read(iss.size))[0] > while True: > buf = f.read(sixtyfour.size) > if not buf: break > data.append(sixtyfour.unpack(buf)[0]) > with open(sys.argv[1], 'wb') as f: > f.write(header) + > if '--index' in sys.argv: + > indexsize = int(indexsize * thirtytwo.size / sixtyfour.size) + > f.write(iss.pack(indexsize)) > for item in data: > f.write(thirtytwo.pack(item)) > EOF @@ -151,6 +157,19 @@ number of merge: 0 number of jumps: 0 + $ "$PYTHON" ../repack.py .hg/cache/evoext-stablesortcache-00 --index + $ f -H .hg/cache/evoext-stablesortcache-00 + .hg/cache/evoext-stablesortcache-00: + 0000: 00 00 00 02 01 24 14 42 b3 c2 bf 32 11 e5 93 b5 |.....$.B...2....| + 0010: 49 c6 55 ea 65 b2 95 e3 00 00 00 0c 00 00 00 00 |I.U.e...........| + 0020: 00 00 00 00 00 00 00 00 |........| + + $ hg debugstablesortcache --debug + number of revisions: 3 + stablesortcache file seems to be corrupted, it will be rebuilt from scratch + number of merge: 0 + number of jumps: 0 + $ "$PYTHON" ../truncate.py .hg/cache/evoext-stablesortcache-00 -4 $ f -H .hg/cache/evoext-stablesortcache-00 .hg/cache/evoext-stablesortcache-00: @@ -297,6 +316,26 @@ max jumps: 1 jump cache size: 12 bytes + $ "$PYTHON" ../repack.py .hg/cache/evoext-stablesortcache-00 --index + $ f -H .hg/cache/evoext-stablesortcache-00 + .hg/cache/evoext-stablesortcache-00: + 0000: 00 00 00 03 2b 6d 66 99 47 cd 52 4d 74 f4 3c 1b |....+mf.G.RMt.<.| + 0010: 11 c7 84 85 89 70 7e ef 00 00 00 10 00 00 00 00 |.....p~.........| + 0020: 00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................| + 0030: 01 00 00 00 02 00 00 00 |........| + + $ hg debugstablesortcache --debug + number of revisions: 4 + stablesortcache file seems to be corrupted, it will be rebuilt from scratch + number of merge: 1 + number of jumps: 1 + average jumps: 1.000 + median jumps: 1 + 90% jumps: 1 + 99% jumps: 1 + max jumps: 1 + jump cache size: 12 bytes + $ "$PYTHON" ../truncate.py .hg/cache/evoext-stablesortcache-00 -4 $ f -H .hg/cache/evoext-stablesortcache-00 .hg/cache/evoext-stablesortcache-00: