mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parse.y: fix here-doc identifier with newline
* parse.y (heredoc_identifier): quoted here-document identifier must end within the same line. the only corner case that here-document identifier can contain a newline is that the closing qoute is placed at the beginning of the next line, and has been warned since 2.4. ```ruby <<"EOS " # warning: here document identifier ends with a newline EOS ```
This commit is contained in:
parent
69cad44fac
commit
330b376133
4 changed files with 14 additions and 16 deletions
6
NEWS
6
NEWS
|
@ -42,6 +42,12 @@ sufficient information, see the ChangeLog file or Redmine
|
|||
* Setting <code>$,</code> to non-nil value is warned now. Use of it in
|
||||
Array#join is warned too.
|
||||
|
||||
* Quoted here-document identifier must end within the same line.
|
||||
|
||||
<<"EOS
|
||||
" # This has been warned since 2.4
|
||||
EOS
|
||||
|
||||
=== Core classes updates (outstanding ones only)
|
||||
|
||||
Enumerable::
|
||||
|
|
|
@ -255,6 +255,9 @@ behaves like Kernel#`:
|
|||
cat #{__FILE__}
|
||||
HEREDOC
|
||||
|
||||
When surrounding with quotes, any characters but that quote and newline
|
||||
can be used as the identifier.
|
||||
|
||||
To call a method on a heredoc place it after the opening identifier:
|
||||
|
||||
expected_result = <<-EXPECTED.chomp
|
||||
|
|
14
parse.y
14
parse.y
|
@ -6788,7 +6788,6 @@ heredoc_identifier(struct parser_params *p)
|
|||
int c = nextc(p), term, func = 0, term_len = 2;
|
||||
enum yytokentype token = tSTRING_BEG;
|
||||
long len;
|
||||
int newline = 0;
|
||||
int indent = 0;
|
||||
|
||||
if (c == '-') {
|
||||
|
@ -6821,23 +6820,14 @@ heredoc_identifier(struct parser_params *p)
|
|||
tokadd(p, func);
|
||||
term = c;
|
||||
while ((c = nextc(p)) != -1 && c != term) {
|
||||
if (c == '\n') goto unterminated;
|
||||
if (tokadd_mbchar(p, c) == -1) return 0;
|
||||
if (!newline && c == '\n') newline = 1;
|
||||
else if (newline) newline = 2;
|
||||
}
|
||||
if (c == -1) {
|
||||
unterminated:
|
||||
yyerror(NULL, p, "unterminated here document identifier");
|
||||
return -1;
|
||||
}
|
||||
switch (newline) {
|
||||
case 1:
|
||||
rb_warn0("here document identifier ends with a newline");
|
||||
if (--p->tokidx > 0 && p->tokenbuf[p->tokidx] == '\r') --p->tokidx;
|
||||
break;
|
||||
case 2:
|
||||
compile_error(p, "here document identifier across newlines, never match");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -852,10 +852,9 @@ eom
|
|||
assert_syntax_error("puts <<""EOS\n""ng\n""EOS\r""NO\n", /can't find string "EOS" anywhere before EOF/)
|
||||
end
|
||||
|
||||
def test_heredoc_newline
|
||||
assert_warn(/ends with a newline/) do
|
||||
eval("<<\"EOS\n\"\nEOS\n")
|
||||
end
|
||||
def test_unterminated_heredoc
|
||||
assert_syntax_error("<<\"EOS\n\nEOS\n", /unterminated/)
|
||||
assert_syntax_error("<<\"EOS\n\"\nEOS\n", /unterminated/)
|
||||
end
|
||||
|
||||
def test__END___cr
|
||||
|
|
Loading…
Reference in a new issue