From 4a31c1e45d12b7813096948616f8a03224f20ac8 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 30 May 2019 12:35:27 +0900 Subject: parse.y: continue after heredoc error * parse.y: continue parsing the rest of the here-document starting line, after the terminator was not found. --- parse.y | 12 ++++++++++-- test/ruby/test_syntax.rb | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/parse.y b/parse.y index 24b8e2ed41..5b33ef4547 100644 --- a/parse.y +++ b/parse.y @@ -6016,12 +6016,17 @@ nextline(struct parser_params *p) return -1; if (!p->lex.input || NIL_P(v = lex_getline(p))) { + end_of_input: p->eofp = 1; lex_goto_eol(p); return -1; } p->cr_seen = FALSE; } + else if (NIL_P(v)) { + /* after here-document without terminator */ + goto end_of_input; + } add_delayed_token(p, p->lex.ptok, p->lex.pend); if (p->heredoc_end > 0) { p->ruby_sourceline = p->heredoc_end; @@ -6056,7 +6061,7 @@ nextc(struct parser_params *p) { int c; - if (UNLIKELY((p->lex.pcur == p->lex.pend) || p->eofp || p->lex.nextline)) { + if (UNLIKELY((p->lex.pcur == p->lex.pend) || p->eofp || RTEST(p->lex.nextline))) { if (nextline(p)) return -1; } c = (unsigned char)*p->lex.pcur++; @@ -7003,6 +7008,8 @@ heredoc_restore(struct parser_params *p, rb_strterm_heredoc_t *here) p->heredoc_end = p->ruby_sourceline; p->ruby_sourceline = (int)here->sourceline; token_flush(p); + if (p->eofp) p->lex.nextline = Qnil; + p->eofp = 0; } static int @@ -7260,7 +7267,8 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here) restore: heredoc_restore(p, &p->lex.strterm->u.heredoc); p->lex.strterm = 0; - return 0; + SET_LEX_STATE(EXPR_END); + return tSTRING_END; } bol = was_bol(p); if (!bol) { diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 4e52bc4a72..6fdca37924 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -901,6 +901,12 @@ 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_no_terminator + assert_syntax_error("puts <<""A\n", /can't find string "A" anywhere before EOF/) + assert_syntax_error("puts <<""A + <<""B\n", /can't find string "A" anywhere before EOF/) + assert_syntax_error("puts <<""A + <<""B\n", /can't find string "B" anywhere before EOF/) + end + def test_unterminated_heredoc assert_syntax_error("<<\"EOS\n\nEOS\n", /unterminated/) assert_syntax_error("<<\"EOS\n\"\nEOS\n", /unterminated/) -- cgit v1.2.3