changeset 37573:49b82cdb5983

patch: error out if reached to EOF while reading hunk This was where out-of-bounds read occurred in old C extension.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 09 Apr 2018 21:06:46 +0900
parents c6b8d614690a
children a1bcc7ff0eac
files mercurial/diffhelpers.py mercurial/patch.py tests/test-import.t
diffstat 3 files changed, 36 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/diffhelpers.py	Mon Apr 09 20:55:05 2018 +0900
+++ b/mercurial/diffhelpers.py	Mon Apr 09 21:06:46 2018 +0900
@@ -7,6 +7,12 @@
 
 from __future__ import absolute_import
 
+from .i18n import _
+
+from . import (
+    error,
+)
+
 def addlines(fp, hunk, lena, lenb, a, b):
     """Read lines from fp into the hunk
 
@@ -22,6 +28,8 @@
             break
         for i in xrange(num):
             s = fp.readline()
+            if not s:
+                raise error.ParseError(_('incomplete hunk'))
             if s == "\\ No newline at end of file\n":
                 fixnewline(hunk, a, b)
                 continue
--- a/mercurial/patch.py	Mon Apr 09 20:55:05 2018 +0900
+++ b/mercurial/patch.py	Mon Apr 09 21:06:46 2018 +0900
@@ -1254,8 +1254,11 @@
             self.lenb = int(self.lenb)
         self.starta = int(self.starta)
         self.startb = int(self.startb)
-        diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a,
-                             self.b)
+        try:
+            diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb,
+                                 self.a, self.b)
+        except error.ParseError as e:
+            raise PatchError(_("bad hunk #%d: %s") % (self.number, e))
         # if we hit eof before finishing out the hunk, the last line will
         # be zero length.  Lets try to fix it up.
         while len(self.hunk[-1]) == 0:
--- a/tests/test-import.t	Mon Apr 09 20:55:05 2018 +0900
+++ b/tests/test-import.t	Mon Apr 09 21:06:46 2018 +0900
@@ -1917,3 +1917,26 @@
   a not tracked!
   abort: source file 'a' does not exist
   [255]
+
+test immature end of hunk
+
+  $ hg import - <<'EOF'
+  > diff --git a/foo b/foo
+  > --- a/foo
+  > --- b/foo
+  > @@ -0,0 +1,1 @@
+  > EOF
+  applying patch from stdin
+  abort: bad hunk #1: incomplete hunk
+  [255]
+
+  $ hg import - <<'EOF'
+  > diff --git a/foo b/foo
+  > --- a/foo
+  > --- b/foo
+  > @@ -0,0 +1,1 @@
+  > \ No newline at end of file
+  > EOF
+  applying patch from stdin
+  abort: bad hunk #1: incomplete hunk
+  [255]