Project

General

Profile

Actions

Bug #18038

closed

Invalid interpolation in heredocs

Added by maciej.mensfeld (Maciej Mensfeld) 3 months ago. Updated 3 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
[ruby-core:104597]

Description

Given code as followed:

var = 1

v1 = <<~CMD
  something
  #{"/#{var}"}
CMD

v2 = <<~CMD
  something
  #{other = "/#{var}"}
CMD

v3 = <<~CMD
  something
  #{("/#{var}")}
CMD

p v1
p v2
p v3

p v1 == v2
p v2 == v3

result of running this:

"something\n/\n"
"something\n/1\n"
"something\n/\n"
false
false

I would expect all heredocs to return the same value for all the cases. It seems the other variable assignment should be irrelevant but only with it the value "1" is present.

Actions #1

Updated by maciej.mensfeld (Maciej Mensfeld) 3 months ago

  • Description updated (diff)

Updated by xtkoba (Tee KOBAYASHI) 3 months ago

It seems that heredoc_dedent in parse.y interacts badly with some sort of interpolation optimizations.

A patch is shown below to disable such optimizations.

--- a/parse.y
+++ b/parse.y
@@ -10184,7 +10184,9 @@ new_evstr(struct parser_params *p, NODE
    switch (nd_type(node)) {
      case NODE_STR:
        nd_set_type(node, NODE_DSTR);
-     case NODE_DSTR: case NODE_EVSTR:
+     case NODE_DSTR:
+       break;
+     case NODE_EVSTR:
        return node;
    }
     }

Updated by eileencodes (Eileen Uchitelle) 3 months ago

I opened a PR here: https://github.com/ruby/ruby/pull/4664

I also confirmed that this is broken in the same way in Ruby 2.5, 2.6, and 2.7

Actions #4

Updated by eileencodes (Eileen Uchitelle) 3 months ago

  • Status changed from Open to Closed

Applied in changeset git|b940a453572b5c3ed5c0951647929e14f5843a7d.


Fix interpolated heredoc

This fixes https://bugs.ruby-lang.org/issues/18038. The provided
reproduction showed that this happens in heredocs with double
interpolation. In this case DSTR was getting returned but needs to be
convered to a EVSTR which is what is returned by the function. There
may be an additional bug here that we weren't able to produce. It seems
odd that STR returns DSTR while everything else should return
EVSTR since the function is new_evstr.

[Bug #18038][ruby-core:104597]

Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org

Actions

Also available in: Atom PDF