1
0
Fork 0
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:
Nobuyoshi Nakada 2019-04-29 00:24:26 +09:00
parent 69cad44fac
commit 330b376133
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60
4 changed files with 14 additions and 16 deletions

6
NEWS
View file

@ -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::

View file

@ -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
View file

@ -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:

View file

@ -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