D2587: cext: accept arguments as Py_buffer
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Sat Mar 3 20:16:07 UTC 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG68026dd7c4f9: cext: accept arguments as Py_buffer (authored by indygreg, committed by ).
CHANGED PRIOR TO COMMIT
https://phab.mercurial-scm.org/D2587?vs=6436&id=6466#toc
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D2587?vs=6436&id=6466
REVISION DETAIL
https://phab.mercurial-scm.org/D2587
AFFECTED FILES
mercurial/cext/bdiff.c
mercurial/mdiff.py
CHANGE DETAILS
diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -30,17 +30,9 @@
fixws = bdiff.fixws
patches = mpatch.patches
patchedsize = mpatch.patchedsize
-_textdiff = bdiff.bdiff
+textdiff = bdiff.bdiff
splitnewlines = bdiff.splitnewlines
-# On Python 3, util.buffer() creates a memoryview, which appears not
-# supporting the buffer protocol
-if pycompat.ispy3:
- def textdiff(a, b):
- return _textdiff(bytes(a), bytes(b))
-else:
- textdiff = _textdiff
-
class diffopts(object):
'''context is the number of context lines
text treats all files as text
diff --git a/mercurial/cext/bdiff.c b/mercurial/cext/bdiff.c
--- a/mercurial/cext/bdiff.c
+++ b/mercurial/cext/bdiff.c
@@ -60,7 +60,8 @@
static PyObject *bdiff(PyObject *self, PyObject *args)
{
- char *sa, *sb, *rb, *ia, *ib;
+ Py_buffer ba, bb;
+ char *rb, *ia, *ib;
PyObject *result = NULL;
struct bdiff_line *al = NULL, *bl = NULL;
struct bdiff_hunk l, *h;
@@ -70,25 +71,39 @@
l.next = NULL;
- if (!PyArg_ParseTuple(args, PY23("s#s#:bdiff", "y#y#:bdiff"), &sa, &la,
- &sb, &lb))
+ if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba, &bb))
return NULL;
+ if (!PyBuffer_IsContiguous(&ba, 'C') || ba.ndim > 1) {
+ PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
+ goto cleanup;
+ }
+
+ if (!PyBuffer_IsContiguous(&bb, 'C') || bb.ndim > 1) {
+ PyErr_SetString(PyExc_ValueError, "bdiff input not contiguous");
+ goto cleanup;
+ }
+
+ la = ba.len;
+ lb = bb.len;
+
if (la > UINT_MAX || lb > UINT_MAX) {
PyErr_SetString(PyExc_ValueError, "bdiff inputs too large");
- return NULL;
+ goto cleanup;
}
_save = PyEval_SaveThread();
lmax = la > lb ? lb : la;
- for (ia = sa, ib = sb; li < lmax && *ia == *ib; ++li, ++ia, ++ib)
+ for (ia = ba.buf, ib = bb.buf; li < lmax && *ia == *ib;
+ ++li, ++ia, ++ib) {
if (*ia == '\n')
lcommon = li + 1;
+ }
/* we can almost add: if (li == lmax) lcommon = li; */
- an = bdiff_splitlines(sa + lcommon, la - lcommon, &al);
- bn = bdiff_splitlines(sb + lcommon, lb - lcommon, &bl);
+ an = bdiff_splitlines(ba.buf + lcommon, la - lcommon, &al);
+ bn = bdiff_splitlines(bb.buf + lcommon, lb - lcommon, &bl);
if (!al || !bl) {
PyErr_NoMemory();
goto cleanup;
@@ -137,6 +152,8 @@
cleanup:
if (_save)
PyEval_RestoreThread(_save);
+ PyBuffer_Release(&ba);
+ PyBuffer_Release(&bb);
if (al) {
free(al);
}
To: indygreg, #hg-reviewers, yuja
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list