# HG changeset patch # User Bram Moolenaar # Date 1368386183 -7200 # Node ID 736b8e18a3bced7e498a6b81e7189d78cf4671e0 # Parent a38216d77e7357e5fc6091a8d701618c79d1d636 updated for version 7.3.943 Problem: Python: Negative indices were failing. Solution: Fix negative indices. Add tests. (ZyX) diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -2394,6 +2394,9 @@ RBItem(BufferObject *self, PyInt n, PyIn 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, Py 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 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -1114,7 +1114,7 @@ BufferSubscript(PyObject *self, PyObject 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, PyObje 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 --- 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 --- 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 --- 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 --- 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 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 943, +/**/ 942, /**/ 941,