[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]