From bd80f35bc59442894a4ec56aefb0137cb0a350fa Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 12 May 2013 21:16:23 +0200 Subject: updated for version 7.3.943 Problem: Python: Negative indices were failing. Solution: Fix negative indices. Add tests. (ZyX) --- src/if_py_both.h | 6 ++++++ src/if_python3.c | 4 ++-- src/testdir/test86.in | 43 ++++++++++++++++++++++++++++++++++++++++++- src/testdir/test86.ok | 13 +++++++++++++ src/testdir/test87.in | 43 ++++++++++++++++++++++++++++++++++++++++++- src/testdir/test87.ok | 13 +++++++++++++ src/version.c | 2 ++ 7 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/if_py_both.h b/src/if_py_both.h index 681b7a172..eca07aebb 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -2394,6 +2394,9 @@ RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end) if (end == -1) end = self->buf->b_ml.ml_line_count; + if (n < 0) + n += end - start + 1; + if (n < 0 || n > end - start) { PyErr_SetString(PyExc_IndexError, _("line number out of range")); @@ -2441,6 +2444,9 @@ RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyI if (end == -1) end = self->buf->b_ml.ml_line_count; + if (n < 0) + n += end - start + 1; + if (n < 0 || n > end - start) { PyErr_SetString(PyExc_IndexError, _("line number out of range")); diff --git a/src/if_python3.c b/src/if_python3.c index da0867b7e..daaf689b4 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -1114,7 +1114,7 @@ BufferSubscript(PyObject *self, PyObject* idx) return NULL; if (PySlice_GetIndicesEx((PyObject *)idx, - (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) { @@ -1146,7 +1146,7 @@ BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val) return -1; if (PySlice_GetIndicesEx((PyObject *)idx, - (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) { diff --git a/src/testdir/test86.in b/src/testdir/test86.in index ca4480754..555a5fdf5 100644 --- a/src/testdir/test86.in +++ b/src/testdir/test86.in @@ -475,9 +475,50 @@ EOF : endtry : endfor : call RecVars(oname) -endtry :endfor :only +:" +:" Test buffer object +:vnew +:put ='First line' +:put ='Second line' +:put ='Third line' +:1 delete _ +:py b=vim.current.buffer +:wincmd w +:mark a +py << EOF +cb = vim.current.buffer +# Tests BufferAppend and BufferItem +cb.append(b[0]) +# Tests BufferSlice and BufferAssSlice +cb.append('abc') # Will be overwritten +cb[-1:] = b[:-2] +# Test BufferLength and BufferAssSlice +cb.append('def') # Will not be overwritten +cb[len(cb):] = b[:] +# Test BufferAssItem and BufferMark +cb.append('ghi') # Will be overwritten +cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) +# Test BufferRepr +cb.append(repr(cb) + repr(b)) +# Modify foreign buffer +b.append('foo') +b[0]='bar' +b[0:0]=['baz'] +vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) +# Test CheckBuffer +vim.command('bwipeout! ' + str(b.number)) +for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")'): + try: + exec(expr) + except vim.error: + pass + else: + # Usually a SEGV here + # Should not happen in any case + cb.append('No exception for ' + expr) +EOF :endfun :" :call Test() diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok index 2acfb98ae..cada813cc 100644 --- a/src/testdir/test86.ok +++ b/src/testdir/test86.ok @@ -306,3 +306,16 @@ bar G: '.,,' W: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,' B: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,' +First line +First line +def +First line +Second line +Third line +(7, 2) + +baz +bar +Second line +Third line +foo diff --git a/src/testdir/test87.in b/src/testdir/test87.in index c2bcb6a33..6f3cce0fa 100644 --- a/src/testdir/test87.in +++ b/src/testdir/test87.in @@ -444,9 +444,50 @@ EOF : endtry : endfor : call RecVars(oname) -endtry :endfor :only +:" +:" Test buffer object +:vnew +:put ='First line' +:put ='Second line' +:put ='Third line' +:1 delete _ +:py3 b=vim.current.buffer +:wincmd w +:mark a +py3 << EOF +cb = vim.current.buffer +# Tests BufferAppend and BufferItem +cb.append(b[0]) +# Tests BufferSlice and BufferAssSlice +cb.append('abc') # Will be overwritten +cb[-1:] = b[:-2] +# Test BufferLength and BufferAssSlice +cb.append('def') # Will not be overwritten +cb[len(cb):] = b[:] +# Test BufferAssItem and BufferMark +cb.append('ghi') # Will be overwritten +cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1])) +# Test BufferRepr +cb.append(repr(cb) + repr(b)) +# Modify foreign buffer +b.append('foo') +b[0]='bar' +b[0:0]=['baz'] +vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number) +# Test CheckBuffer +vim.command('bwipeout! ' + str(b.number)) +for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")'): + try: + exec(expr) + except vim.error: + pass + else: + # Usually a SEGV here + # Should not happen in any case + cb.append('No exception for ' + expr) +EOF :endfun :" :call Test() diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok index 72e7b059f..a43698d16 100644 --- a/src/testdir/test87.ok +++ b/src/testdir/test87.ok @@ -295,3 +295,16 @@ bar G: '.,,' W: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,' B: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,' +First line +First line +def +First line +Second line +Third line +(7, 2) + +baz +bar +Second line +Third line +foo diff --git a/src/version.c b/src/version.c index be2138c05..63476f7bc 100644 --- a/src/version.c +++ b/src/version.c @@ -728,6 +728,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 943, /**/ 942, /**/ -- cgit v1.2.1