Patchwork [1,of,6] bundle2: safely read unpack data from part header

login
register
mail settings
Submitter Pierre-Yves David
Date April 1, 2014, 7:35 p.m.
Message ID <831918d356d52dc62a97.1396380922@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/4179/
State Accepted
Commit 662b79be093cae1af1d389ade5f00fefc6018d6a
Headers show

Comments

Pierre-Yves David - April 1, 2014, 7:35 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1396336095 25200
#      Tue Apr 01 00:08:15 2014 -0700
# Node ID 831918d356d52dc62a97e4675a7eefef581f6b90
# Parent  f312031f1fd91b687043ef38f3f0cea4532ee346
bundle2: safely read unpack data from part header

We use the same approach that the other unpack, as function is given the struct
format and his both responsible for reading the right amount of data from the
header and unpack the struct.

This give use flexibility if we decide to change the size of something in the
format before the release.

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -290,20 +290,26 @@  class unbundle20(object):
             """return the next <size> byte from the header"""
             offset = self._offset
             data = headerblock[offset:(offset + size)]
             self._offset = offset + size
             return data
-        typesize = _unpack(_fparttypesize, fromheader(1))[0]
+        def unpackheader(format):
+            """read given format from header
+
+            This automatically compute the size of the format to read."""
+            data = fromheader(struct.calcsize(format))
+            return _unpack(format, data)
+
+        typesize = unpackheader(_fparttypesize)[0]
         parttype = fromheader(typesize)
         self.ui.debug('part type: "%s"\n' % parttype)
         ## reading parameters
         # param count
-        mancount, advcount = _unpack(_fpartparamcount, fromheader(2))
+        mancount, advcount = unpackheader(_fpartparamcount)
         self.ui.debug('part parameters: %i\n' % (mancount + advcount))
         # param size
-        paramsizes = _unpack(_makefpartparamsizes(mancount + advcount),
-                             fromheader(2*(mancount + advcount)))
+        paramsizes = unpackheader(_makefpartparamsizes(mancount + advcount))
         # make it a list of couple again
         paramsizes = zip(paramsizes[::2], paramsizes[1::2])
         # split mandatory from advisory
         mansizes = paramsizes[:mancount]
         advsizes = paramsizes[mancount:]