summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-11-11 09:35:37 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-11-11 09:38:14 +0900
commitade038889468e7755d7ebfe75975e0e77d1e1dec (patch)
tree33319d9eda7d2dd56f85da6a1db182ac3a745b87
parentb42656b9c403da1bac8e1dd7534f0a7a09df67b0 (diff)
Fixed embedded document with EOF char
-rw-r--r--parse.y20
-rw-r--r--test/ruby/test_parse.rb9
2 files changed, 25 insertions, 4 deletions
diff --git a/parse.y b/parse.y
index e23439294b..e84468d2a5 100644
--- a/parse.y
+++ b/parse.y
@@ -7391,6 +7391,19 @@ whole_match_p(struct parser_params *p, const char *eos, long len, int indent)
return strncmp(eos, ptr, len) == 0;
}
+static int
+word_match_p(struct parser_params *p, const char *word, long len)
+{
+ if (strncmp(p->lex.pcur, word, len)) return 0;
+ if (p->lex.pcur + len == p->lex.pend) return 1;
+ int c = (unsigned char)p->lex.pcur[len];
+ if (ISSPACE(c)) return 1;
+ switch (c) {
+ case '\0': case '\004': case '\032': return 1;
+ }
+ return 0;
+}
+
#define NUM_SUFFIX_R (1<<0)
#define NUM_SUFFIX_I (1<<1)
#define NUM_SUFFIX_ALL 3
@@ -8976,7 +8989,7 @@ parser_yylex(struct parser_params *p)
case '=':
if (was_bol(p)) {
/* skip embedded rd document */
- if (strncmp(p->lex.pcur, "begin", 5) == 0 && ISSPACE(p->lex.pcur[5])) {
+ if (word_match_p(p, "begin", 5)) {
int first_p = TRUE;
lex_goto_eol(p);
@@ -8992,11 +9005,10 @@ parser_yylex(struct parser_params *p)
compile_error(p, "embedded document meets end of file");
return 0;
}
- if (c != '=') continue;
- if (c == '=' && strncmp(p->lex.pcur, "end", 3) == 0 &&
- (p->lex.pcur + 3 == p->lex.pend || ISSPACE(p->lex.pcur[3]))) {
+ if (c == '=' && word_match_p(p, "end", 3)) {
break;
}
+ pushback(p, c);
}
lex_goto_eol(p);
dispatch_scan_event(p, tEMBDOC_END);
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index ee5f815fd6..2622ec529c 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -709,6 +709,15 @@ x = __ENCODING__
def test_embedded_rd
assert_valid_syntax("=begin\n""=end")
+ assert_valid_syntax("=begin\n""=end\0")
+ assert_valid_syntax("=begin\n""=end\C-d")
+ assert_valid_syntax("=begin\n""=end\C-z")
+ end
+
+ def test_embedded_rd_error
+ error = 'embedded document meets end of file'
+ assert_syntax_error("=begin\n", error)
+ assert_syntax_error("=begin", error)
end
def test_float