From 5931857281ce45c1c277aa86d1588119ab00a955 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 3 Aug 2019 13:41:55 +0900 Subject: [PATCH] Fix dangling path name from fstring * parse.y (yycompile): make sure in advance that the `__FILE__` object shares a fstring, to get rid of dangling path name. Fixed up 53e9908d8afc7f03109b0aafd1698ab35f512b05. [Bug #16041] * vm_eval.c (eval_make_iseq): ditto. --- parse.y | 4 ++-- test/ruby/test_eval.rb | 11 +++++++++++ vm_eval.c | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/parse.y b/parse.y index 3bff42ac56..de2a92285c 100644 --- a/parse.y +++ b/parse.y @@ -5812,7 +5812,7 @@ yycompile(VALUE vparser, struct parser_params *p, VALUE fname, int line) p->ruby_sourcefile = "(none)"; } else { - p->ruby_sourcefile_string = rb_str_new_frozen(fname); + p->ruby_sourcefile_string = rb_fstring(fname); p->ruby_sourcefile = StringValueCStr(fname); } p->ruby_sourceline = line - 1; @@ -9773,7 +9773,7 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc) if (NIL_P(file)) file = rb_str_new(0, 0); else - file = rb_str_dup(rb_fstring(file)); + file = rb_str_dup(file); node = NEW_STR(add_mark_object(p, file), loc); } return node; diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb index 49bb3305e4..3d6116edbc 100644 --- a/test/ruby/test_eval.rb +++ b/test/ruby/test_eval.rb @@ -498,6 +498,17 @@ class TestEval < Test::Unit::TestCase }, '[Bug #10368]' end + def test_gced_eval_location + Dir.mktmpdir do |d| + File.write("#{d}/2.rb", "") + File.write("#{d}/1.rb", "require_relative '2'\n""__FILE__\n") + file = "1.rb" + path = File.expand_path(file, d) + assert_equal(path, eval(File.read(path), nil, File.expand_path(file, d))) + assert_equal(path, eval(File.read(path), nil, File.expand_path(file, d))) + end + end + def orphan_proc proc {eval("return :ng")} end diff --git a/vm_eval.c b/vm_eval.c index 9281ebd40e..2cb04af5b2 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1284,6 +1284,7 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind, } if (fname != Qundef) { + if (!NIL_P(fname)) fname = rb_fstring(fname); realpath = fname; } else if (bind) { @@ -1293,7 +1294,7 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind, rb_parser_warn_location(parser, TRUE); } else { - fname = rb_usascii_str_new_cstr("(eval)"); + fname = rb_fstring_lit("(eval)"); } rb_parser_set_context(parser, base_block, FALSE);