From a0a95edb2d664f4e339d923e7072fe5112918921 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 30 Jul 2024 06:26:09 +0800 Subject: [PATCH] vim-patch:9.1.0638: E1510 may happen when formatting a message for smsg() (#29907) Problem: E1510 may happen when formatting a message (after 9.1.0181). Solution: Only give E1510 when using typval. (zeertzjq) closes: vim/vim#15391 https://github.com/vim/vim/commit/0dff31576a340b74cec81517912923c38cb28450 (cherry picked from commit d131c48c823c30f519506eddcaef662dad5afa43) --- src/nvim/strings.c | 76 +++++++++++++++-------------- test/old/testdir/test_spellfile.vim | 16 ++++++ 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/nvim/strings.c b/src/nvim/strings.c index cc61b24f16..ec14606ef9 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1002,7 +1002,7 @@ static void format_overflow_error(const char *pstart) enum { MAX_ALLOWED_STRING_WIDTH = 6400, }; -static int get_unsigned_int(const char *pstart, const char **p, unsigned *uj) +static int get_unsigned_int(const char *pstart, const char **p, unsigned *uj, bool overflow_err) { *uj = (unsigned)(**p - '0'); (*p)++; @@ -1013,8 +1013,12 @@ static int get_unsigned_int(const char *pstart, const char **p, unsigned *uj) } if (*uj > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(pstart); - return FAIL; + if (overflow_err) { + format_overflow_error(pstart); + return FAIL; + } else { + *uj = MAX_ALLOWED_STRING_WIDTH; + } } return OK; @@ -1075,7 +1079,7 @@ static int parse_fmt_types(const char ***ap_types, int *num_posarg, const char * // Positional argument unsigned uj; - if (get_unsigned_int(pstart, &p, &uj) == FAIL) { + if (get_unsigned_int(pstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1118,7 +1122,7 @@ static int parse_fmt_types(const char ***ap_types, int *num_posarg, const char * // Positional argument field width unsigned uj; - if (get_unsigned_int(arg + 1, &p, &uj) == FAIL) { + if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1144,7 +1148,7 @@ static int parse_fmt_types(const char ***ap_types, int *num_posarg, const char * const char *digstart = p; unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1165,7 +1169,7 @@ static int parse_fmt_types(const char ***ap_types, int *num_posarg, const char * // Parse precision unsigned uj; - if (get_unsigned_int(arg + 1, &p, &uj) == FAIL) { + if (get_unsigned_int(arg + 1, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1192,7 +1196,7 @@ static int parse_fmt_types(const char ***ap_types, int *num_posarg, const char * const char *digstart = p; unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1488,7 +1492,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st const char *digstart = p; unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1530,7 +1534,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st // Positional argument field width unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1539,15 +1543,19 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st p++; } - const int j = (tvs - ? (int)tv_nr(tvs, &arg_idx) - : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx, - &arg_cur, fmt), - va_arg(ap, int))); + int j = (tvs + ? (int)tv_nr(tvs, &arg_idx) + : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx, + &arg_cur, fmt), + va_arg(ap, int))); if (j > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); - goto error; + if (tvs != NULL) { + format_overflow_error(digstart); + goto error; + } else { + j = MAX_ALLOWED_STRING_WIDTH; + } } if (j >= 0) { @@ -1562,12 +1570,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st const char *digstart = p; unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { - goto error; - } - - if (uj > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1585,12 +1588,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st const char *digstart = p; unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { - goto error; - } - - if (uj > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1604,7 +1602,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st // positional argument unsigned uj; - if (get_unsigned_int(digstart, &p, &uj) == FAIL) { + if (get_unsigned_int(digstart, &p, &uj, tvs != NULL) == FAIL) { goto error; } @@ -1613,15 +1611,19 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st p++; } - const int j = (tvs - ? (int)tv_nr(tvs, &arg_idx) - : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx, - &arg_cur, fmt), - va_arg(ap, int))); + int j = (tvs + ? (int)tv_nr(tvs, &arg_idx) + : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx, + &arg_cur, fmt), + va_arg(ap, int))); if (j > MAX_ALLOWED_STRING_WIDTH) { - format_overflow_error(digstart); - goto error; + if (tvs != NULL) { + format_overflow_error(digstart); + goto error; + } else { + j = MAX_ALLOWED_STRING_WIDTH; + } } if (j >= 0) { diff --git a/test/old/testdir/test_spellfile.vim b/test/old/testdir/test_spellfile.vim index 4d2a6cf35f..f3046efa74 100644 --- a/test/old/testdir/test_spellfile.vim +++ b/test/old/testdir/test_spellfile.vim @@ -757,6 +757,22 @@ func Test_spell_add_word() %bw! endfunc +func Test_spell_add_long_word() + set spell spellfile=./Xspellfile.add spelllang=en + + let word = repeat('a', 9000) + let v:errmsg = '' + " Spell checking doesn't really work for such a long word, + " but this should not cause an E1510 error. + exe 'spellgood ' .. word + call assert_equal('', v:errmsg) + call assert_equal([word], readfile('./Xspellfile.add')) + + set spell& spellfile= spelllang& encoding=utf-8 + call delete('./Xspellfile.add') + call delete('./Xspellfile.add.spl') +endfunc + func Test_spellfile_verbose() call writefile(['1', 'one'], 'XtestVerbose.dic') call writefile([], 'XtestVerbose.aff')