From 62351ff3d2fba336f09569d844a7b6f7f36a078d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 4 May 2023 17:20:48 +0800 Subject: [PATCH] vim-patch:8.2.1466: Vim9: cannot index or slice a variable with type "any" Problem: Vim9: cannot index or slice a variable with type "any". Solution: Add runtime index and slice. https://github.com/vim/vim/commit/cc673e746ab98566556ff964d7a76f2fb46d7f84 Missing changes from the last PR. Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0a41ffd4bf..a14b098caf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7289,8 +7289,8 @@ char *char_from_string(char *str, varnumber_T index) /// "str_len". /// If going over the end return "str_len". /// If "idx" is negative count from the end, -1 is the last character. -/// When going over the start return zero. -static size_t char_idx2byte(char *str, size_t str_len, varnumber_T idx) +/// When going over the start return -1. +static ssize_t char_idx2byte(char *str, size_t str_len, varnumber_T idx) { varnumber_T nchar = idx; size_t nbyte = 0; @@ -7307,8 +7307,11 @@ static size_t char_idx2byte(char *str, size_t str_len, varnumber_T idx) nbyte -= (size_t)utf_head_off(str, str + nbyte); nchar++; } + if (nchar < 0) { + return -1; + } } - return nbyte; + return (ssize_t)nbyte; } /// Return the slice "str[first:last]" using character indexes. @@ -7319,22 +7322,25 @@ char *string_slice(char *str, varnumber_T first, varnumber_T last) return NULL; } size_t slen = strlen(str); - size_t start_byte = char_idx2byte(str, slen, first); - size_t end_byte; + ssize_t start_byte = char_idx2byte(str, slen, first); + if (start_byte < 0) { + start_byte = 0; // first index very negative: use zero + } + ssize_t end_byte; if (last == -1) { - end_byte = slen; + end_byte = (ssize_t)slen; } else { end_byte = char_idx2byte(str, slen, last); - if (end_byte < slen) { + if (end_byte >= 0 && end_byte < (ssize_t)slen) { // end index is inclusive - end_byte += (size_t)utf_ptr2len(str + end_byte); + end_byte += utf_ptr2len(str + end_byte); } } - if (start_byte >= slen || end_byte <= start_byte) { + if (start_byte >= (ssize_t)slen || end_byte <= start_byte) { return NULL; } - return xstrnsave(str + start_byte, end_byte - start_byte); + return xstrnsave(str + start_byte, (size_t)(end_byte - start_byte)); } /// Handle: