Skip to content

Commit 1f5175d

Browse files
zeertzjqchrisbra
authored andcommitted
patch 9.1.0313: Crash when using heredoc with comment in command block
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>
1 parent e74cad3 commit 1f5175d

6 files changed

Lines changed: 52 additions & 26 deletions

File tree

src/charset.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,17 +2088,6 @@ skiptowhite(char_u *p)
20882088
return p;
20892089
}
20902090

2091-
/*
2092-
* skiptowhite: skip over text until ' ' or '\t' or newline or NUL.
2093-
*/
2094-
char_u *
2095-
skiptowhite_or_nl(char_u *p)
2096-
{
2097-
while (*p != ' ' && *p != '\t' && *p != NL && *p != NUL)
2098-
++p;
2099-
return p;
2100-
}
2101-
21022091
/*
21032092
* skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
21042093
*/

src/evalvars.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,15 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
781781
int count = 0;
782782
int heredoc_in_string = FALSE;
783783
char_u *line_arg = NULL;
784+
char_u *nl_ptr = vim_strchr(cmd, '\n');
784785

785-
if (eap->ea_getline == NULL && vim_strchr(cmd, '\n') == NULL)
786+
if (nl_ptr != NULL)
787+
{
788+
heredoc_in_string = TRUE;
789+
line_arg = nl_ptr + 1;
790+
*nl_ptr = NUL;
791+
}
792+
else if (eap->ea_getline == NULL)
786793
{
787794
emsg(_(e_cannot_use_heredoc_here));
788795
return NULL;
@@ -826,14 +833,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
826833
if (*cmd != NUL && *cmd != comment_char)
827834
{
828835
marker = skipwhite(cmd);
829-
p = skiptowhite_or_nl(marker);
830-
if (*p == NL)
831-
{
832-
// heredoc in a string
833-
line_arg = p + 1;
834-
heredoc_in_string = TRUE;
835-
}
836-
else if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
836+
p = skiptowhite(marker);
837+
if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
837838
{
838839
semsg(_(e_trailing_characters_str), p);
839840
return NULL;

src/proto/charset.pro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ int vim_isalpha(int c);
6161
int vim_toupper(int c);
6262
int vim_tolower(int c);
6363
char_u *skiptowhite(char_u *p);
64-
char_u *skiptowhite_or_nl(char_u *p);
6564
char_u *skiptowhite_esc(char_u *p);
6665
long getdigits(char_u **pp);
6766
long getdigits_quoted(char_u **pp);

src/testdir/test_let.vim

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,13 @@ END
536536
XX
537537
call assert_equal(['Line1'], var1)
538538

539+
let var1 =<< trim XX " comment
540+
Line1
541+
Line2
542+
Line3
543+
XX
544+
call assert_equal(['Line1', ' Line2', 'Line3'], var1)
545+
539546
" ignore "endfunc"
540547
let var1 =<< END
541548
something
@@ -716,15 +723,27 @@ END
716723
call v9.CheckScriptFailure(lines, 'E15:')
717724

718725
" Test for using heredoc in a single string using execute()
719-
call assert_equal(["['one', 'two']"],
720-
\ execute("let x =<< trim END\n one\n two\nEND\necho x")->split("\n"))
721-
call assert_equal(["[' one', ' two']"],
722-
\ execute("let x =<< END\n one\n two\nEND\necho x")->split("\n"))
726+
call assert_equal("\n['one', 'two']",
727+
\ execute("let x =<< trim END\n one\n two\nEND\necho x"))
728+
call assert_equal("\n['one', ' two']",
729+
\ execute("let x =<< trim END\n one\n two\nEND\necho x"))
730+
call assert_equal("\n['one', 'two']",
731+
\ execute(" let x =<< trim END\n one\n two\n END\necho x"))
732+
call assert_equal("\n['one', ' two']",
733+
\ execute(" let x =<< trim END\n one\n two\n END\necho x"))
734+
call assert_equal("\n[' one', ' two']",
735+
\ execute("let x =<< END\n one\n two\nEND\necho x"))
736+
call assert_equal("\n['one', 'two']",
737+
\ execute("let x =<< END\none\ntwo\nEND\necho x"))
738+
call assert_equal("\n['one', 'two']",
739+
\ execute("let x =<< END \" comment\none\ntwo\nEND\necho x"))
723740
let cmd = 'execute("let x =<< END\n one\n two\necho x")'
724741
call assert_fails(cmd, "E990: Missing end marker 'END'")
725742
let cmd = 'execute("let x =<<\n one\n two\necho x")'
726-
call assert_fails(cmd, "E990: Missing end marker ''")
743+
call assert_fails(cmd, "E172: Missing marker")
727744
let cmd = 'execute("let x =<< trim\n one\n two\necho x")'
745+
call assert_fails(cmd, "E172: Missing marker")
746+
let cmd = 'execute("let x =<< end\n one\n two\nend\necho x")'
728747
call assert_fails(cmd, "E221: Marker cannot start with lower case letter")
729748
let cmd = 'execute("let x =<< eval END\n one\n two{y}\nEND\necho x")'
730749
call assert_fails(cmd, 'E121: Undefined variable: y')

src/testdir/test_vim9_script.vim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,22 @@ def Test_command_block_heredoc()
508508
CODE
509509
v9.CheckSourceSuccess(lines)
510510

511+
# Heredoc with comment
512+
lines =<< trim CODE
513+
vim9script
514+
com SomeCommand {
515+
g:someVar =<< trim END # comment
516+
aaa
517+
bbb
518+
END
519+
}
520+
execute('SomeCommand')
521+
assert_equal(['aaa', 'bbb'], g:someVar)
522+
delcommand SomeCommand
523+
unlet g:someVar
524+
CODE
525+
v9.CheckSourceSuccess(lines)
526+
511527
# heredoc evaluation
512528
lines =<< trim CODE
513529
vim9script

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
313,
707709
/**/
708710
312,
709711
/**/

0 commit comments

Comments
 (0)