changeset 15589:44ea60ca593b v8.1.0802

patch 8.1.0802: negative index doesn't work for Blob commit https://github.com/vim/vim/commit/a5be9b62480a6f338a72c01e57c9edd0bca8048b Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 24 12:31:44 2019 +0100 patch 8.1.0802: negative index doesn't work for Blob Problem: Negative index doesn't work for Blob. Solution: Make it work, add a test. (closes https://github.com/vim/vim/issues/3856)
author Bram Moolenaar <Bram@vim.org>
date Thu, 24 Jan 2019 12:45:05 +0100
parents d1b7f02e6d29
children cb9859388af8
files src/blob.c src/eval.c src/proto/blob.pro src/testdir/test_blob.vim src/version.c
diffstat 5 files changed, 20 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/blob.c
+++ b/src/blob.c
@@ -72,8 +72,12 @@ blob_copy(typval_T *from, typval_T *to)
 	int  len = from->vval.v_blob->bv_ga.ga_len;
 
 	if (len > 0)
+	{
 	    to->vval.v_blob->bv_ga.ga_data =
 			    vim_memsave(from->vval.v_blob->bv_ga.ga_data, len);
+	    if (to->vval.v_blob->bv_ga.ga_data == NULL)
+		len = 0;
+	}
 	to->vval.v_blob->bv_ga.ga_len = len;
     }
     return ret;
@@ -112,7 +116,7 @@ blob_len(blob_T *b)
  * Get byte "idx" in blob "b".
  * Caller must check that "idx" is valid.
  */
-    char_u
+    int
 blob_get(blob_T *b, int idx)
 {
     return ((char_u*)b->bv_ga.ga_data)[idx];
--- a/src/eval.c
+++ b/src/eval.c
@@ -4723,12 +4723,13 @@ eval_index(
 		}
 		else
 		{
-		    // The resulting variable is a string of a single
-		    // character.  If the index is too big or negative the
-		    // result is empty.
+		    // The resulting variable is a byte value.
+		    // If the index is too big or negative that is an error.
+		    if (n1 < 0)
+			n1 = len + n1;
 		    if (n1 < len && n1 >= 0)
 		    {
-			int v = (int)blob_get(rettv->vval.v_blob, n1);
+			int v = blob_get(rettv->vval.v_blob, n1);
 
 			clear_tv(rettv);
 			rettv->v_type = VAR_NUMBER;
--- a/src/proto/blob.pro
+++ b/src/proto/blob.pro
@@ -6,7 +6,7 @@ int blob_copy(typval_T *from, typval_T *
 void blob_free(blob_T *b);
 void blob_unref(blob_T *b);
 long blob_len(blob_T *b);
-char_u blob_get(blob_T *b, int idx);
+int blob_get(blob_T *b, int idx);
 void blob_set(blob_T *b, int idx, char_u c);
 int blob_equal(blob_T *b1, blob_T *b2);
 int read_blob(FILE *fd, blob_T *blob);
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -95,6 +95,13 @@ func Test_blob_get()
   call assert_equal(999, get(b, 5, 999))
   call assert_equal(-1, get(b, -8))
   call assert_equal(999, get(b, -8, 999))
+
+  call assert_equal(0x00, b[0])
+  call assert_equal(0x22, b[2])
+  call assert_equal(0x44, b[4])
+  call assert_equal(0x44, b[-1])
+  call assert_fails('echo b[5]', 'E979:')
+  call assert_fails('echo b[-8]', 'E979:')
 endfunc
 
 func Test_blob_to_string()
--- a/src/version.c
+++ b/src/version.c
@@ -792,6 +792,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    802,
+/**/
     801,
 /**/
     800,