Mercurial > evolve
changeset 5872:bdda94ea2195 stable
evolve: check stablesortcache index size before unpacking (issue6354)
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Tue, 13 Apr 2021 19:46:03 +0800 |
parents | d6fa75241975 |
children | ee242f4a2d73 |
files | hgext3rd/evolve/stablesort.py tests/test-cache-corruption.t |
diffstat | 2 files changed, 40 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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('<q') # as seen on 64-bit platforms > thirtytwo = struct.Struct('<l') # as seen on 32-bit platforms + > iss = struct.Struct('<I') # for rewriting indexsize of stablesortcache > 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: