summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-18 15:29:37 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-18 15:29:37 +0000
commit091f98cf8c34c4288d0a3afcddd566ab652a30fb (patch)
tree143c36ff8c569f7606a9c46039574ee299a52510
parentca310ba6f7a37d43ab977429081747bed44816e5 (diff)
merge revision(s) 53573: [Backport #11989]
* parse.y (parser_here_document): an escaped newline is not an actual newline, and the rest part should not be dedented. [ruby-core:72855] [Bug #11989] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@62826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--parse.y90
-rw-r--r--test/ruby/test_syntax.rb9
-rw-r--r--version.h2
4 files changed, 48 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 9a1ebeb27d..fd0e113fd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Mar 19 00:28:28 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (parser_here_document): an escaped newline is not an
+ actual newline, and the rest part should not be dedented.
+ [ruby-core:72855] [Bug #11989]
+
Mon Mar 19 00:27:06 2018 Koichi Sasada <ko1@atdot.net>
thread_pthread: do not corrupt stack
diff --git a/parse.y b/parse.y
index ba3d683da0..a4afdd6dca 100644
--- a/parse.y
+++ b/parse.y
@@ -6632,10 +6632,13 @@ parser_heredoc_restore(struct parser_params *parser, NODE *here)
}
static int
-dedent_pos(const char *str, long len, int width)
+dedent_string(VALUE string, int width)
{
+ char *str;
+ long len;
int i, col = 0;
+ RSTRING_GETMEM(string, str, len);
for (i = 0; i < len && col < width; i++) {
if (str[i] == ' ') {
col++;
@@ -6649,65 +6652,38 @@ dedent_pos(const char *str, long len, int width)
break;
}
}
+ MEMMOVE(str, str + i, char, len - i);
+ rb_str_set_len(string, len - i);
return i;
}
#ifndef RIPPER
-static VALUE
-parser_heredoc_dedent_string(VALUE input, int width, int first)
-{
- long len;
- int col;
- char *str, *p, *out_p, *end, *t;
-
- RSTRING_GETMEM(input, str, len);
- end = &str[len];
-
- p = str;
- if (!first) {
- p = memchr(p, '\n', end - p);
- if (!p) return input;
- p++;
- }
- out_p = p;
- while (p < end) {
- col = dedent_pos(p, end - p, width);
- p += col;
- if (!(t = memchr(p, '\n', end - p)))
- t = end;
- else
- ++t;
- if (p > out_p) memmove(out_p, p, t - p);
- out_p += t - p;
- p = t;
- }
- rb_str_set_len(input, out_p - str);
-
- return input;
-}
-
static void
parser_heredoc_dedent(struct parser_params *parser, NODE *root)
{
NODE *node, *str_node;
- int first = TRUE;
+ int bol = TRUE;
int indent = heredoc_indent;
if (indent <= 0) return;
node = str_node = root;
+ if (!root) return;
+ if (nd_type(root) == NODE_ARRAY) str_node = root->nd_head;
+
while (str_node) {
VALUE lit = str_node->nd_lit;
- if (NIL_P(parser_heredoc_dedent_string(lit, indent, first)))
- compile_error(PARSER_ARG "dedent failure: %d: %"PRIsVALUE, indent, lit);
- first = FALSE;
+ if (bol) dedent_string(lit, indent);
+ bol = TRUE;
str_node = 0;
while ((node = node->nd_next) != 0 && nd_type(node) == NODE_ARRAY) {
if ((str_node = node->nd_head) != 0) {
enum node_type type = nd_type(str_node);
if (type == NODE_STR || type == NODE_DSTR) break;
+ bol = FALSE;
+ str_node = 0;
}
}
}
@@ -6724,17 +6700,12 @@ parser_heredoc_dedent(struct parser_params *parser, VALUE array)
static VALUE
parser_dedent_string(VALUE self, VALUE input, VALUE width)
{
- char *str;
- long len;
int wid, col;
StringValue(input);
wid = NUM2UINT(width);
rb_str_modify(input);
- RSTRING_GETMEM(input, str, len);
- col = dedent_pos(str, len, wid);
- MEMMOVE(str, str + col, char, len - col);
- rb_str_set_len(input, len - col);
+ col = dedent_string(input, wid);
return INT2NUM(col);
}
#endif
@@ -6890,15 +6861,7 @@ parser_here_document(struct parser_params *parser, NODE *here)
}
if (!(func & STR_FUNC_EXPAND)) {
- int end = 0;
do {
-#ifdef RIPPER
- if (end && heredoc_indent > 0) {
- set_yylval_str(str);
- flush_string_content(enc);
- return tSTRING_CONTENT;
- }
-#endif
p = RSTRING_PTR(lex_lastline);
pend = lex_pend;
if (pend > p) {
@@ -6926,6 +6889,11 @@ parser_here_document(struct parser_params *parser, NODE *here)
str = STR_NEW(p, pend - p);
if (pend < lex_pend) rb_str_cat(str, "\n", 1);
lex_goto_eol(parser);
+ if (heredoc_indent > 0) {
+ set_yylval_str(str);
+ flush_string_content(enc);
+ return tSTRING_CONTENT;
+ }
if (nextc() == -1) {
if (str) {
dispose_string(str);
@@ -6933,7 +6901,7 @@ parser_here_document(struct parser_params *parser, NODE *here)
}
goto error;
}
- } while (!(end = whole_match_p(eos, len, indent)));
+ } while (!whole_match_p(eos, len, indent));
}
else {
/* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
@@ -6951,20 +6919,16 @@ parser_here_document(struct parser_params *parser, NODE *here)
goto restore;
}
if (c != '\n') {
-#ifdef RIPPER
flush:
-#endif
set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
flush_string_content(enc);
return tSTRING_CONTENT;
}
tokadd(nextc());
-#ifdef RIPPER
- if (c == '\n' && heredoc_indent > 0) {
+ if (heredoc_indent > 0) {
lex_goto_eol(parser);
goto flush;
}
-#endif
/* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
if ((c = nextc()) == -1) goto error;
} while (!whole_match_p(eos, len, indent));
@@ -9000,6 +8964,16 @@ literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
head = list_append(node, head);
htype = NODE_DSTR;
}
+ if (heredoc_indent > 0) {
+ switch (htype) {
+ case NODE_STR:
+ nd_set_type(head, NODE_DSTR);
+ case NODE_DSTR:
+ return list_append(head, tail);
+ default:
+ break;
+ }
+ }
switch (nd_type(tail)) {
case NODE_STR:
if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 29851b79de..91594c013a 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -612,6 +612,15 @@ e"
assert_dedented_heredoc(expect, result)
end
+ def test_dedented_heredoc_with_newline
+ bug11989 = '[ruby-core:72855] [Bug #11989] after escaped newline should not be dedented'
+ result = ' x\n'" y\n" \
+ " z\n"
+ expect = 'x\n'" y\n" \
+ "z\n"
+ assert_dedented_heredoc(expect, result, bug11989)
+ end
+
def test_dedented_heredoc_with_concatenation
bug11990 = '[ruby-core:72857] [Bug #11990] concatenated string should not be dedented'
%w[eos "eos" 'eos'].each do |eos|
diff --git a/version.h b/version.h
index 845428a7a6..5a363b8a1c 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.3.7"
#define RUBY_RELEASE_DATE "2018-03-19"
-#define RUBY_PATCHLEVEL 426
+#define RUBY_PATCHLEVEL 427
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3