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]
This commit is contained in:
parent
616d671758
commit
57d315c937
Notes:
git
2021-09-14 23:55:34 +09:00
12
hash.c
12
hash.c
@ -6182,6 +6182,18 @@ env_to_hash(void)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_envtbl(void)
|
||||||
|
{
|
||||||
|
return envtbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_env_to_hash(void)
|
||||||
|
{
|
||||||
|
return env_to_hash();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ENV.to_hash -> hash of name/value pairs
|
* ENV.to_hash -> hash of name/value pairs
|
||||||
|
11
process.c
11
process.c
@ -177,6 +177,9 @@ static void check_uid_switch(void);
|
|||||||
static void check_gid_switch(void);
|
static void check_gid_switch(void);
|
||||||
static int exec_async_signal_safe(const struct rb_execarg *, char *, size_t);
|
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
|
#if 1
|
||||||
#define p_uid_from_name p_uid_from_name
|
#define p_uid_from_name p_uid_from_name
|
||||||
#define p_gid_from_name p_gid_from_name
|
#define p_gid_from_name p_gid_from_name
|
||||||
@ -315,7 +318,7 @@ static ID id_pgroup;
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static ID id_new_pgroup;
|
static ID id_new_pgroup;
|
||||||
#endif
|
#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_nanosecond, id_microsecond, id_millisecond, id_second;
|
||||||
static ID id_float_microsecond, id_float_millisecond, id_float_second;
|
static ID id_float_microsecond, id_float_millisecond, id_float_second;
|
||||||
static ID id_GETTIMEOFDAY_BASED_CLOCK_REALTIME, id_TIME_BASED_CLOCK_REALTIME;
|
static ID id_GETTIMEOFDAY_BASED_CLOCK_REALTIME, id_TIME_BASED_CLOCK_REALTIME;
|
||||||
@ -2978,8 +2981,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
|
|||||||
envtbl = rb_hash_new();
|
envtbl = rb_hash_new();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
envtbl = rb_const_get(rb_cObject, id_ENV);
|
envtbl = rb_env_to_hash();
|
||||||
envtbl = rb_to_hash_type(envtbl);
|
|
||||||
}
|
}
|
||||||
hide_obj(envtbl);
|
hide_obj(envtbl);
|
||||||
if (envopts != Qfalse) {
|
if (envopts != Qfalse) {
|
||||||
@ -3591,7 +3593,7 @@ save_env(struct rb_execarg *sargp)
|
|||||||
if (!sargp)
|
if (!sargp)
|
||||||
return;
|
return;
|
||||||
if (sargp->env_modification == Qfalse) {
|
if (sargp->env_modification == Qfalse) {
|
||||||
VALUE env = rb_const_get(rb_cObject, id_ENV);
|
VALUE env = rb_envtbl();
|
||||||
if (RTEST(env)) {
|
if (RTEST(env)) {
|
||||||
VALUE ary = hide_obj(rb_ary_new());
|
VALUE ary = hide_obj(rb_ary_new());
|
||||||
rb_block_call(env, idEach, 0, 0, save_env_i,
|
rb_block_call(env, idEach, 0, 0, save_env_i,
|
||||||
@ -9061,7 +9063,6 @@ Init_process(void)
|
|||||||
id_chdir = rb_intern_const("chdir");
|
id_chdir = rb_intern_const("chdir");
|
||||||
id_umask = rb_intern_const("umask");
|
id_umask = rb_intern_const("umask");
|
||||||
id_close_others = rb_intern_const("close_others");
|
id_close_others = rb_intern_const("close_others");
|
||||||
id_ENV = rb_intern_const("ENV");
|
|
||||||
id_nanosecond = rb_intern_const("nanosecond");
|
id_nanosecond = rb_intern_const("nanosecond");
|
||||||
id_microsecond = rb_intern_const("microsecond");
|
id_microsecond = rb_intern_const("microsecond");
|
||||||
id_millisecond = rb_intern_const("millisecond");
|
id_millisecond = rb_intern_const("millisecond");
|
||||||
|
@ -261,6 +261,18 @@ class TestProcess < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
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]
|
MANDATORY_ENVS = %w[RUBYLIB MJIT_SEARCH_BUILD_DIR]
|
||||||
case RbConfig::CONFIG['target_os']
|
case RbConfig::CONFIG['target_os']
|
||||||
when /linux/
|
when /linux/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user