summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-04-13 17:52:26 +0200
committerChristian Brabandt <cb@256bit.org>2024-04-13 17:52:26 +0200
commit1f5175d9af3d3f37e19f23e0e6f84caec47390f2 (patch)
tree2f1e6a3bdb9378b763d9990a6375fe1678cd8eac
parente74cad3321ce1dcefc1fc64f617511275b6cd930 (diff)
patch 9.1.0313: Crash when using heredoc with comment in command blockv9.1.0313
Problem: Crash when using heredoc with comment in command block. Solution: Handle a newline more like the end of the line, fix coverity warning (zeertzjq). closes: #14535 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--src/charset.c11
-rw-r--r--src/evalvars.c19
-rw-r--r--src/proto/charset.pro1
-rw-r--r--src/testdir/test_let.vim29
-rw-r--r--src/testdir/test_vim9_script.vim16
-rw-r--r--src/version.c2
6 files changed, 52 insertions, 26 deletions
diff --git a/src/charset.c b/src/charset.c
index 4dcde149f3..470698f0e0 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2089,17 +2089,6 @@ skiptowhite(char_u *p)
}
/*
- * skiptowhite: skip over text until ' ' or '\t' or newline or NUL.
- */
- char_u *
-skiptowhite_or_nl(char_u *p)
-{
- while (*p != ' ' && *p != '\t' && *p != NL && *p != NUL)
- ++p;
- return p;
-}
-
-/*
* skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
*/
char_u *
diff --git a/src/evalvars.c b/src/evalvars.c
index 62728ed8ab..d4dd0add2a 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -781,8 +781,15 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
int count = 0;
int heredoc_in_string = FALSE;
char_u *line_arg = NULL;
+ char_u *nl_ptr = vim_strchr(cmd, '\n');
- if (eap->ea_getline == NULL && vim_strchr(cmd, '\n') == NULL)
+ if (nl_ptr != NULL)
+ {
+ heredoc_in_string = TRUE;
+ line_arg = nl_ptr + 1;
+ *nl_ptr = NUL;
+ }
+ else if (eap->ea_getline == NULL)
{
emsg(_(e_cannot_use_heredoc_here));
return NULL;
@@ -826,14 +833,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
if (*cmd != NUL && *cmd != comment_char)
{
marker = skipwhite(cmd);
- p = skiptowhite_or_nl(marker);
- if (*p == NL)
- {
- // heredoc in a string
- line_arg = p + 1;
- heredoc_in_string = TRUE;
- }
- else if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
+ p = skiptowhite(marker);
+ if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
{
semsg(_(e_trailing_characters_str), p);
return NULL;
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index a4f6c453d9..a74731931d 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -61,7 +61,6 @@ int vim_isalpha(int c);
int vim_toupper(int c);
int vim_tolower(int c);
char_u *skiptowhite(char_u *p);
-char_u *skiptowhite_or_nl(char_u *p);
char_u *skiptowhite_esc(char_u *p);
long getdigits(char_u **pp);
long getdigits_quoted(char_u **pp);
diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim
index e6d9cae8e5..974e8f1a37 100644
--- a/src/testdir/test_let.vim
+++ b/src/testdir/test_let.vim
@@ -536,6 +536,13 @@ END
XX
call assert_equal(['Line1'], var1)
+ let var1 =<< trim XX " comment
+ Line1
+ Line2
+ Line3
+ XX
+ call assert_equal(['Line1', ' Line2', 'Line3'], var1)
+
" ignore "endfunc"
let var1 =<< END
something
@@ -716,15 +723,27 @@ END
call v9.CheckScriptFailure(lines, 'E15:')
" Test for using heredoc in a single string using execute()
- call assert_equal(["['one', 'two']"],
- \ execute("let x =<< trim END\n one\n two\nEND\necho x")->split("\n"))
- call assert_equal(["[' one', ' two']"],
- \ execute("let x =<< END\n one\n two\nEND\necho x")->split("\n"))
+ call assert_equal("\n['one', 'two']",
+ \ execute("let x =<< trim END\n one\n two\nEND\necho x"))
+ call assert_equal("\n['one', ' two']",
+ \ execute("let x =<< trim END\n one\n two\nEND\necho x"))
+ call assert_equal("\n['one', 'two']",
+ \ execute(" let x =<< trim END\n one\n two\n END\necho x"))
+ call assert_equal("\n['one', ' two']",
+ \ execute(" let x =<< trim END\n one\n two\n END\necho x"))
+ call assert_equal("\n[' one', ' two']",
+ \ execute("let x =<< END\n one\n two\nEND\necho x"))
+ call assert_equal("\n['one', 'two']",
+ \ execute("let x =<< END\none\ntwo\nEND\necho x"))
+ call assert_equal("\n['one', 'two']",
+ \ execute("let x =<< END \" comment\none\ntwo\nEND\necho x"))
let cmd = 'execute("let x =<< END\n one\n two\necho x")'
call assert_fails(cmd, "E990: Missing end marker 'END'")
let cmd = 'execute("let x =<<\n one\n two\necho x")'
- call assert_fails(cmd, "E990: Missing end marker ''")
+ call assert_fails(cmd, "E172: Missing marker")
let cmd = 'execute("let x =<< trim\n one\n two\necho x")'
+ call assert_fails(cmd, "E172: Missing marker")
+ let cmd = 'execute("let x =<< end\n one\n two\nend\necho x")'
call assert_fails(cmd, "E221: Marker cannot start with lower case letter")
let cmd = 'execute("let x =<< eval END\n one\n two{y}\nEND\necho x")'
call assert_fails(cmd, 'E121: Undefined variable: y')
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 136c81db7d..a3f21bed02 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -508,6 +508,22 @@ def Test_command_block_heredoc()
CODE
v9.CheckSourceSuccess(lines)
+ # Heredoc with comment
+ lines =<< trim CODE
+ vim9script
+ com SomeCommand {
+ g:someVar =<< trim END # comment
+ aaa
+ bbb
+ END
+ }
+ execute('SomeCommand')
+ assert_equal(['aaa', 'bbb'], g:someVar)
+ delcommand SomeCommand
+ unlet g:someVar
+ CODE
+ v9.CheckSourceSuccess(lines)
+
# heredoc evaluation
lines =<< trim CODE
vim9script
diff --git a/src/version.c b/src/version.c
index 1a924e7232..dd7f2035ee 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 313,
+/**/
312,
/**/
311,