Patchwork [5,of,5] bundle2: detect and disallow a negative chunk size

login
register
mail settings
Submitter Pierre-Yves David
Date Oct. 15, 2014, 8:18 p.m.
Message ID <f52ea5af3c55e6846d99.1413404311@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/6307/
State Accepted
Headers show

Comments

Pierre-Yves David - Oct. 15, 2014, 8:18 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1413368845 25200
#      Wed Oct 15 03:27:25 2014 -0700
# Node ID f52ea5af3c55e6846d9988a3b7741d6f5b6b975b
# Parent  91c0c243dae1d965bfb159c86445875188b9068a
bundle2: detect and disallow a negative chunk size

We have no usage planned for 2/3 of them and the support for the planned
usecase is not here yet. So we raise a BundleValueError when encountered
Augie Fackler - Oct. 17, 2014, 2:27 p.m.
On Wed, Oct 15, 2014 at 01:18:31PM -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1413368845 25200
> #      Wed Oct 15 03:27:25 2014 -0700
> # Node ID f52ea5af3c55e6846d9988a3b7741d6f5b6b975b
> # Parent  91c0c243dae1d965bfb159c86445875188b9068a
> bundle2: detect and disallow a negative chunk size

Queued. I'll try to remember to fix your all your base reference in-flight ;)

>
> We have no usage planned for 2/3 of them and the support for the planned
> usecase is not here yet. So we raise a BundleValueError when encountered
>
> diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
> --- a/mercurial/bundle2.py
> +++ b/mercurial/bundle2.py
> @@ -507,10 +507,13 @@ class unbundle20(unpackermixin):
>      def params(self):
>          """dictionary of stream level parameters"""
>          self.ui.debug('reading bundle2 stream parameters\n')
>          params = {}
>          paramssize = self._unpack(_fstreamparamsize)[0]
> +        if paramssize < 0:
> +            raise error.BundleValueError('negative bundle param size: %i'
> +                                         % paramssize)
>          if paramssize:
>              for p in self._readexact(paramssize).split(' '):
>                  p = p.split('=', 1)
>                  p = [urllib.unquote(i) for i in p]
>                  if len(p) < 2:
> @@ -556,10 +559,13 @@ class unbundle20(unpackermixin):
>      def _readpartheader(self):
>          """reads a part header size and return the bytes blob
>
>          returns None if empty"""
>          headersize = self._unpack(_fpartheadersize)[0]
> +        if headersize < 0:
> +            raise error.BundleValueError('negative part header size: %i'
> +                                         % headersize)
>          self.ui.debug('part header size: %i\n' % headersize)
>          if headersize:
>              return self._readexact(headersize)
>          return None
>
> @@ -763,10 +769,13 @@ class unbundlepart(unpackermixin):
>          ## part payload
>          def payloadchunks():
>              payloadsize = self._unpack(_fpayloadsize)[0]
>              self.ui.debug('payload chunk size: %i\n' % payloadsize)
>              while payloadsize:
> +                if payloadsize < 0:
> +                    msg = 'negative payload chunk size: %i' % payloadsize
> +                    raise error.BundleValueError(msg)
>                  yield self._readexact(payloadsize)
>                  payloadsize = self._unpack(_fpayloadsize)[0]
>                  self.ui.debug('payload chunk size: %i\n' % payloadsize)
>          self._payloadstream = util.chunkbuffer(payloadchunks())
>          # we read the data, tell it
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -507,10 +507,13 @@  class unbundle20(unpackermixin):
     def params(self):
         """dictionary of stream level parameters"""
         self.ui.debug('reading bundle2 stream parameters\n')
         params = {}
         paramssize = self._unpack(_fstreamparamsize)[0]
+        if paramssize < 0:
+            raise error.BundleValueError('negative bundle param size: %i'
+                                         % paramssize)
         if paramssize:
             for p in self._readexact(paramssize).split(' '):
                 p = p.split('=', 1)
                 p = [urllib.unquote(i) for i in p]
                 if len(p) < 2:
@@ -556,10 +559,13 @@  class unbundle20(unpackermixin):
     def _readpartheader(self):
         """reads a part header size and return the bytes blob
 
         returns None if empty"""
         headersize = self._unpack(_fpartheadersize)[0]
+        if headersize < 0:
+            raise error.BundleValueError('negative part header size: %i'
+                                         % headersize)
         self.ui.debug('part header size: %i\n' % headersize)
         if headersize:
             return self._readexact(headersize)
         return None
 
@@ -763,10 +769,13 @@  class unbundlepart(unpackermixin):
         ## part payload
         def payloadchunks():
             payloadsize = self._unpack(_fpayloadsize)[0]
             self.ui.debug('payload chunk size: %i\n' % payloadsize)
             while payloadsize:
+                if payloadsize < 0:
+                    msg = 'negative payload chunk size: %i' % payloadsize
+                    raise error.BundleValueError(msg)
                 yield self._readexact(payloadsize)
                 payloadsize = self._unpack(_fpayloadsize)[0]
                 self.ui.debug('payload chunk size: %i\n' % payloadsize)
         self._payloadstream = util.chunkbuffer(payloadchunks())
         # we read the data, tell it