summaryrefslogtreecommitdiff
path: root/ruby.c
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2021-10-09 15:08:38 +0900
committernagachika <nagachika@ruby-lang.org>2021-10-09 15:08:38 +0900
commit2c947e74a0a11fe6c54253c15224dc80054c62a2 (patch)
treea1762cf792182842d3bcbd94ba05018095c1c30e /ruby.c
parentfe9d33beb78d5c7932a5c2ca3953045c0ae751d5 (diff)
merge revision(s) 60d0421ca861944459f52292d65dbf0ece26e38a,b6534691a16d751d59fc572d5dddebcaeb21f007,409dbc951b9875d27bd73748c88e15386473cffb,842b0008c132dd587f09766a228041afb7fed24f: [Backport #18191]
Fix the encoding of loaded feature names [Bug #18191] The feature names loaded from the default load paths should also be in the file system encoding. --- ruby.c | 12 +++++++++++- test/ruby/test_require.rb | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) Copy path strings as interned strings --- ruby.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) Replace expanded load path only when modified --- ruby.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) Skip broken strings as the locale encoding --- internal/string.h | 1 + ruby.c | 11 +++++++---- string.c | 6 ++++++ 3 files changed, 14 insertions(+), 4 deletions(-)
Diffstat (limited to 'ruby.c')
-rw-r--r--ruby.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/ruby.c b/ruby.c
index 9990882423..2251fde4e2 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1667,6 +1667,17 @@ tty_enabled(void)
#endif
static VALUE
+copy_str(VALUE str, rb_encoding *enc, bool intern)
+{
+ if (!intern) {
+ if (rb_enc_str_coderange_scan(str, enc) == ENC_CODERANGE_BROKEN)
+ return 0;
+ return rb_enc_associate(rb_str_dup(str), enc);
+ }
+ return rb_enc_interned_str(RSTRING_PTR(str), RSTRING_LEN(str), enc);
+}
+
+static VALUE
process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
{
rb_ast_t *ast = 0;
@@ -1682,6 +1693,8 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
char fbuf[MAXPATHLEN];
int i = (int)proc_options(argc, argv, opt, 0);
unsigned int dump = opt->dump & dump_exit_bits;
+ rb_vm_t *vm = GET_VM();
+ const long loaded_before_enc = RARRAY_LEN(vm->loaded_features);
if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) {
int tty = isatty(1);
@@ -1883,7 +1896,6 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_obj_freeze(opt->script_name);
if (IF_UTF8_PATH(uenc != lenc, 1)) {
long i;
- rb_vm_t *vm = GET_VM();
VALUE load_path = vm->load_path;
const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
int modifiable = FALSE;
@@ -1897,7 +1909,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
if (newpath == path) continue;
path = newpath;
#else
- path = rb_enc_associate(rb_str_dup(path), lenc);
+ if (!(path = copy_str(path, lenc, !mark))) continue;
#endif
if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
if (!modifiable) {
@@ -1910,6 +1922,19 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_ary_replace(vm->load_path_snapshot, load_path);
}
}
+ {
+ VALUE loaded_features = vm->loaded_features;
+ bool modified = false;
+ for (long i = loaded_before_enc; i < RARRAY_LEN(loaded_features); ++i) {
+ VALUE path = RARRAY_AREF(loaded_features, i);
+ if (!(path = copy_str(path, IF_UTF8_PATH(uenc, lenc), true))) continue;
+ modified = true;
+ RARRAY_ASET(loaded_features, i, path);
+ }
+ if (modified) {
+ rb_ary_replace(vm->loaded_features_snapshot, loaded_features);
+ }
+ }
if (opt->features.mask & COMPILATION_FEATURES) {
VALUE option = rb_hash_new();