patch: error out if reached to EOF while reading hunk
This was where out-of-bounds read occurred in old C extension.
--- 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]