From 4fca2b2f02bf64c51de9871ce9fab9e8383fa1eb Mon Sep 17 00:00:00 2001 From: timeless Date: Thu, 31 Mar 2016 02:05:28 +0000 Subject: [PATCH] mpatch: unify mpatchError (issue5182) The pure version was mpatch was throwing struct.error or ValueError for errors, whereas the C version was throwing an "mpatch.mpatchError". Introducing an mpatch.mpatchError into pure and using it consistently is fairly easy, but the actual form for it is mercurial.mpatch.mpatchError, so with this commit, we change the C implementation to match the naming convention too. --- mercurial/mpatch.c | 6 ++++-- mercurial/pure/mpatch.py | 11 +++++++++-- tests/test-revlog.t | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mercurial/mpatch.c b/mercurial/mpatch.c index 9653783c3e..713d3ce5f4 100644 --- a/mercurial/mpatch.c +++ b/mercurial/mpatch.c @@ -404,7 +404,8 @@ PyMODINIT_FUNC PyInit_mpatch(void) if (m == NULL) return NULL; - mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL); + mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError", + NULL, NULL); Py_INCREF(mpatch_Error); PyModule_AddObject(m, "mpatchError", mpatch_Error); @@ -415,6 +416,7 @@ PyMODINIT_FUNC initmpatch(void) { Py_InitModule3("mpatch", methods, mpatch_doc); - mpatch_Error = PyErr_NewException("mpatch.mpatchError", NULL, NULL); + mpatch_Error = PyErr_NewException("mercurial.mpatch.mpatchError", + NULL, NULL); } #endif diff --git a/mercurial/pure/mpatch.py b/mercurial/pure/mpatch.py index 9c08013df1..b52f317bda 100644 --- a/mercurial/pure/mpatch.py +++ b/mercurial/pure/mpatch.py @@ -12,6 +12,10 @@ import struct StringIO = cStringIO.StringIO +class mpatchError(Exception): + """error raised when a delta cannot be decoded + """ + # This attempts to apply a series of patches in time proportional to # the total size of the patches, rather than patches * len(text). This # means rather than shuffling strings around, we shuffle around @@ -84,7 +88,10 @@ def patches(a, bins): last = 0 while pos < end: m.seek(pos) - p1, p2, l = struct.unpack(">lll", m.read(12)) + try: + p1, p2, l = struct.unpack(">lll", m.read(12)) + except struct.error: + raise mpatchError("patch cannot be decoded") _pull(new, frags, p1 - last) # what didn't change _pull([], frags, p2 - p1) # what got deleted new.append((l, pos + 12)) # what got added @@ -114,7 +121,7 @@ def patchedsize(orig, delta): outlen += length if bin != binend: - raise ValueError("patch cannot be decoded") + raise mpatchError("patch cannot be decoded") outlen += orig - last return outlen diff --git a/tests/test-revlog.t b/tests/test-revlog.t index 1741c629b4..30f589b2cf 100644 --- a/tests/test-revlog.t +++ b/tests/test-revlog.t @@ -11,5 +11,5 @@ Test for CVE-2016-3630 rev offset length delta linkrev nodeid p1 p2 0 0 19 -1 2 99e0332bd498 000000000000 000000000000 1 19 12 0 3 6674f57a23d8 99e0332bd498 000000000000 - $ hg debugdata a.i 1 2>&1 | grep decoded - mpatch.mpatchError: patch cannot be decoded + $ hg debugdata a.i 1 2>&1 | egrep 'Error:.*decoded' + mercurial.mpatch.mpatchError: patch cannot be decoded