ruby-changes:67985
From: Jeremy <ko1@a...>
Date: Tue, 14 Sep 2021 23:55:26 +0900 (JST)
Subject: [ruby-changes:67985] 57d315c937 (master): Handle overwriting Object::ENV in spawn
https://git.ruby-lang.org/ruby.git/commit/?id=57d315c937 From 57d315c937e79199af2b77f21f5eecaca85ffac8 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Mon, 13 Sep 2021 11:59:04 -0700 Subject: Handle overwriting Object::ENV in spawn Instead of looking for Object::ENV (which can be overwritten), directly look for the envtbl variable. As that is static in hash.c, and the lookup code is in process.c, add a couple non-static functions that will return envtbl (or envtbl#to_hash). Fixes [Bug #18164] --- hash.c | 12 ++++++++++++ process.c | 11 ++++++----- test/ruby/test_process.rb | 12 ++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/hash.c b/hash.c index f75e394..fd21a99 100644 --- a/hash.c +++ b/hash.c @@ -6182,6 +6182,18 @@ env_to_hash(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L6182 return hash; } +VALUE +rb_envtbl(void) +{ + return envtbl; +} + +VALUE +rb_env_to_hash(void) +{ + return env_to_hash(); +} + /* * call-seq: * ENV.to_hash -> hash of name/value pairs diff --git a/process.c b/process.c index 8c0f112..2e40400 100644 --- a/process.c +++ b/process.c @@ -177,6 +177,9 @@ static void check_uid_switch(void); https://github.com/ruby/ruby/blob/trunk/process.c#L177 static void check_gid_switch(void); static int exec_async_signal_safe(const struct rb_execarg *, char *, size_t); +VALUE rb_envtbl(void); +VALUE rb_env_to_hash(void); + #if 1 #define p_uid_from_name p_uid_from_name #define p_gid_from_name p_gid_from_name @@ -315,7 +318,7 @@ static ID id_pgroup; https://github.com/ruby/ruby/blob/trunk/process.c#L318 #ifdef _WIN32 static ID id_new_pgroup; #endif -static ID id_unsetenv_others, id_chdir, id_umask, id_close_others, id_ENV; +static ID id_unsetenv_others, id_chdir, id_umask, id_close_others; static ID id_nanosecond, id_microsecond, id_millisecond, id_second; static ID id_float_microsecond, id_float_millisecond, id_float_second; static ID id_GETTIMEOFDAY_BASED_CLOCK_REALTIME, id_TIME_BASED_CLOCK_REALTIME; @@ -2978,8 +2981,7 @@ rb_execarg_parent_start1(VALUE execarg_obj) https://github.com/ruby/ruby/blob/trunk/process.c#L2981 envtbl = rb_hash_new(); } else { - envtbl = rb_const_get(rb_cObject, id_ENV); - envtbl = rb_to_hash_type(envtbl); + envtbl = rb_env_to_hash(); } hide_obj(envtbl); if (envopts != Qfalse) { @@ -3591,7 +3593,7 @@ save_env(struct rb_execarg *sargp) https://github.com/ruby/ruby/blob/trunk/process.c#L3593 if (!sargp) return; if (sargp->env_modification == Qfalse) { - VALUE env = rb_const_get(rb_cObject, id_ENV); + VALUE env = rb_envtbl(); if (RTEST(env)) { VALUE ary = hide_obj(rb_ary_new()); rb_block_call(env, idEach, 0, 0, save_env_i, @@ -9061,7 +9063,6 @@ Init_process(void) https://github.com/ruby/ruby/blob/trunk/process.c#L9063 id_chdir = rb_intern_const("chdir"); id_umask = rb_intern_const("umask"); id_close_others = rb_intern_const("close_others"); - id_ENV = rb_intern_const("ENV"); id_nanosecond = rb_intern_const("nanosecond"); id_microsecond = rb_intern_const("microsecond"); id_millisecond = rb_intern_const("millisecond"); diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 80d2eef..07aa584 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -261,6 +261,18 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L261 } end + def test_overwrite_ENV + assert_separately([],"#{<<~"begin;"}\n#{<<~"end;"}") + BUG = "[ruby-core:105223] [Bug #18164]" + begin; + $VERBOSE = nil + ENV = {} + pid = spawn({}, *#{TRUECOMMAND.inspect}) + ENV.replace({}) + assert_kind_of(Integer, pid, BUG) + end; + end + MANDATORY_ENVS = %w[RUBYLIB MJIT_SEARCH_BUILD_DIR] case RbConfig::CONFIG['target_os'] when /linux/ -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/