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: