From 2aaa9af75989bb0993a44e9690ed2ca890b2ff91 Mon Sep 17 00:00:00 2001 From: nagachika Date: Thu, 9 Nov 2023 17:36:42 +0900 Subject: [PATCH] merge revision(s) 4329554f171fdb483cafa672df5f2a08741940c5,b5c74d548872388921402ff2db36be15e924a89b: [Backport #19985] [Bug #19985] Raise LoadError with the converted feature name `Kernel#require` converts feature name objects that have the `to_path` method such as `Pathname`, but had used the original object on error and had resulted in an unexpected `TypeError`. --- load.c | 14 +++++++++++--- test/ruby/test_require.rb | 26 +++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) Ease the `Encoding::CompatibilityError` test failure At the time this test first started using `assert_raise_with_message`, it did not touch `Encoding.default_internal`. --- test/ruby/test_require.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- load.c | 14 +++++++++++--- test/ruby/test_require.rb | 29 +++++++++++++++++++++++------ version.h | 2 +- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/load.c b/load.c index f3d39c2c08..f0219fcf50 100644 --- a/load.c +++ b/load.c @@ -893,6 +893,7 @@ load_unlock(rb_vm_t *vm, const char *ftptr, int done) } } +static VALUE rb_require_string_internal(VALUE fname); /* * call-seq: @@ -955,7 +956,7 @@ rb_f_require_relative(VALUE obj, VALUE fname) rb_loaderror("cannot infer basepath"); } base = rb_file_dirname(base); - return rb_require_string(rb_file_absolute_path(fname, base)); + return rb_require_string_internal(rb_file_absolute_path(fname, base)); } typedef int (*feature_func)(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn); @@ -1164,7 +1165,6 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa volatile bool reset_ext_config = false; struct rb_ext_config prev_ext_config; - fname = rb_get_path(fname); path = rb_str_encode_ospath(fname); RUBY_DTRACE_HOOK(REQUIRE_ENTRY, RSTRING_PTR(fname)); saved_path = path; @@ -1289,6 +1289,12 @@ ruby_require_internal(const char *fname, unsigned int len) VALUE rb_require_string(VALUE fname) +{ + return rb_require_string_internal(FilePathValue(fname)); +} + +static VALUE +rb_require_string_internal(VALUE fname) { rb_execution_context_t *ec = GET_EC(); int result = require_internal(ec, fname, 1, RTEST(ruby_verbose)); @@ -1306,7 +1312,9 @@ rb_require_string(VALUE fname) VALUE rb_require(const char *fname) { - return rb_require_string(rb_str_new_cstr(fname)); + struct RString fake; + VALUE str = rb_setup_fake_str(&fake, fname, strlen(fname), 0); + return rb_require_string_internal(str); } #if EXTSTATIC diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb index 8f902aebae..afbcae2e59 100644 --- a/test/ruby/test_require.rb +++ b/test/ruby/test_require.rb @@ -6,11 +6,27 @@ require 'tmpdir' class TestRequire < Test::Unit::TestCase def test_load_error_path - filename = "should_not_exist" - error = assert_raise(LoadError) do - require filename - end - assert_equal filename, error.path + Tempfile.create(["should_not_exist", ".rb"]) {|t| + filename = t.path + t.close + File.unlink(filename) + + error = assert_raise(LoadError) do + require filename + end + assert_equal filename, error.path + + # with --disable=gems + assert_separately(["-", filename], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + filename = ARGV[0] + path = Struct.new(:to_path).new(filename) + error = assert_raise(LoadError) do + require path + end + assert_equal filename, error.path + end; + } end def test_require_invalid_shared_object @@ -52,7 +68,8 @@ class TestRequire < Test::Unit::TestCase def test_require_nonascii bug3758 = '[ruby-core:31915]' ["\u{221e}", "\x82\xa0".force_encoding("cp932")].each do |path| - assert_raise_with_message(LoadError, /#{path}\z/, bug3758) {require path} + e = assert_raise(LoadError, bug3758) {require path} + assert_operator(e.message, :end_with?, path, bug3758) end end diff --git a/version.h b/version.h index fd676b3049..9f9bb7d5bb 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 127 +#define RUBY_PATCHLEVEL 128 #include "ruby/version.h" #include "ruby/internal/abi.h"