changeset 23868:405eacbecc52

bundle2: enforce parttype as alphanumerical The binary format description has always stated that the parttype should be simple, but it was never really enforced. Recent discussions 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.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 18 Dec 2014 19:14:01 -0800
parents 049a9e3a078d
children d9967b82394a
files mercurial/bundle2.py
diffstat 1 files changed, 11 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/bundle2.py	Wed Jan 14 22:40:39 2015 -0500
+++ b/mercurial/bundle2.py	Thu Dec 18 19:14:01 2014 -0800
@@ -85,7 +85,7 @@
 
     :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.
@@ -153,6 +153,7 @@
 import obsolete
 import pushkey
 import url
+import re
 
 import changegroup, error
 from i18n import _
@@ -171,6 +172,13 @@
 
 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
 
@@ -191,6 +199,7 @@
             '''process a part of type "my part".'''
             ...
     """
+    validateparttype(parttype)
     def _decorator(func):
         lparttype = parttype.lower() # enforce lower case matching.
         assert lparttype not in parthandlermapping
@@ -590,6 +599,7 @@
 
     def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
                  data='', mandatory=True):
+        validateparttype(parttype)
         self.id = None
         self.type = parttype
         self._data = data