From: nobu@... Date: 2017-03-11T01:43:14+00:00 Subject: [ruby-core:80007] [Ruby trunk Feature#13300] Strip chroot path from $LOADED_FEATURES when calling Dir.chroot Issue #13300 has been updated by Nobuyoshi Nakada. Should not use `features_index_add`. By replacing `$LOADED_FEATURES`, the internal snapshot will be invalidated. And doesn't `$LOAD_PATH` need to be stripped? ```diff diff --git a/dir.c b/dir.c index 365f059b0f..3b55e4f4a0 100644 --- a/dir.c +++ b/dir.c @@ -1119,10 +1119,42 @@ check_dirname(VALUE dir) static VALUE dir_s_chroot(VALUE dir, VALUE path) { + VALUE features = rb_gv_get("$LOADED_FEATURES"); + VALUE chroot_to; + path = check_dirname(path); + chroot_to = rb_file_s_expand_path(1, &path); if (chroot(RSTRING_PTR(path)) == -1) rb_sys_fail_path(path); + if (rb_type(features) == RUBY_T_ARRAY && + rb_type(chroot_to) == RUBY_T_STRING) { + long i, features_len, chroot_len, feature_min_len; + VALUE feature, old_features = 0; + char * chroot_str = RSTRING_PTR(chroot_to); + + features_len = RARRAY_LEN(features); + chroot_len = RSTRING_LEN(chroot_to); + feature_min_len = chroot_len + 1; + + for (i=0; i < features_len; i++) { + feature = RARRAY_AREF(features, i); + if ((rb_type(feature) == RUBY_T_STRING) && + RSTRING_LEN(feature) > feature_min_len && + strncmp(chroot_str, RSTRING_PTR(feature), chroot_len) == 0) { + if (!old_features) { + features = rb_ary_dup(old_features = features); + } + feature = rb_str_substr(feature, chroot_len, + RSTRING_LEN(feature)); + RARRAY_ASET(features, i, feature); + } + } + if (old_features) { + rb_ary_replace(old_features, features); + } + } + return INT2FIX(0); } #else ``` ---------------------------------------- Feature #13300: Strip chroot path from $LOADED_FEATURES when calling Dir.chroot https://bugs.ruby-lang.org/issues/13300#change-63424 * Author: Jeremy Evans * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- Currently, `Dir.chroot` doesn't modify `$LOADED_FEATURES`, leading to a situation where `Kernel#require` will attempt to load the same file twice, or a different file not at all because it thinks it is already loaded. With this example code: ~~~ ruby require 'fileutils' File.write('baz.rb', 'A = 1') require './baz' pwd = Dir.pwd Dir.chroot(pwd) require './baz' FileUtils.mkdir_p(pwd) File.write(File.join(pwd, 'baz.rb'), '$a = 2') require "#{pwd}/baz" warn "$a => #{$a.inspect}" unless $a == 2 ~~~ Previous output on stderr: ~~~ /baz.rb:1: warning: already initialized constant A /home/billg/baz.rb:1: warning: previous definition of A was here $a => nil ~~~ With this patch, no output on stderr. ---Files-------------------------------- 0001-Strip-chroot-path-from-LOADED_FEATURES-when-calling-.patch (2.6 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: