[PATCH] bundle2: enforce parttype as alphanumerical

Pierre-Yves David pierre-yves.david at ens-lyon.org
Fri Jan 16 10:30:33 UTC 2015


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1418958841 28800
#      Thu Dec 18 19:14:01 2014 -0800
# Node ID 0f1be09c71fcc524eb66815003752abc41477587
# Parent  81349f4b47f4c793873290852808ff095ab24c00
bundle2: enforce parttype as alphanumerical

The binary format description have always state that the parttype should simple,
but it was never really enforced. Recent discussion have convinced me we want to
keep the part type simple and easy to debug. There is enough extensibility in
the rest of the format.

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -83,11 +83,11 @@ Binary format is as follow
 
     The binary format of the header is has follow
 
     :typesize: (one byte)
 
-    :parttype: alphanumerical part name
+    :parttype: alphanumerical part name (restricted to ^a-zA-Z0-9_:-])
 
     :partid: A 32bits integer (unique in the bundle) that can be used to refer
              to this part.
 
     :parameters:
@@ -151,10 +151,11 @@ import struct
 import urllib
 import string
 import obsolete
 import pushkey
 import url
+import re
 
 import changegroup, error
 from i18n import _
 
 _pack = struct.pack
@@ -169,10 +170,17 @@ from i18n import _
 _fpayloadsize = '>i'
 _fpartparamcount = '>BB'
 
 preferedchunksize = 4096
 
+_parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
+
+def validateparttype(parttype):
+    """raise ValueError if a parttype contains invalid character"""
+    if _parttypeforbidden.match(parttype):
+        raise ValueError(parttype)
+
 def _makefpartparamsizes(nbparams):
     """return a struct format to read part parameter sizes
 
     The number parameters is variable so we need to build that format
     dynamically.
@@ -189,10 +197,11 @@ def parthandler(parttype, params=()):
         @parthandler('myparttype', ('mandatory', 'param', 'handled'))
         def myparttypehandler(...):
             '''process a part of type "my part".'''
             ...
     """
+    validateparttype(parttype)
     def _decorator(func):
         lparttype = parttype.lower() # enforce lower case matching.
         assert lparttype not in parthandlermapping
         parthandlermapping[lparttype] = func
         func.params = frozenset(params)
@@ -588,10 +597,11 @@ class bundlepart(object):
     Both data and parameters cannot be modified after the generation has begun.
     """
 
     def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
                  data='', mandatory=True):
+        validateparttype(parttype)
         self.id = None
         self.type = parttype
         self._data = data
         self._mandatoryparams = list(mandatoryparams)
         self._advisoryparams = list(advisoryparams)


More information about the Mercurial-devel mailing list