* hash.c (env_select): fix memory leak and crash on Windows, make
  keys array first instead of iterating on envrion directly.
  [ruby-dev:48325] [Bug #9978]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46557 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-06-25 23:28:04 +00:00
Родитель 7eeaf208b4
Коммит 78c763a25c
3 изменённых файлов: 31 добавлений и 11 удалений

Просмотреть файл

@ -1,3 +1,9 @@
Thu Jun 26 08:28:01 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* hash.c (env_select): fix memory leak and crash on Windows, make
keys array first instead of iterating on envrion directly.
[ruby-dev:48325] [Bug #9978]
Thu Jun 26 02:45:04 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval_error.c (error_print): put a newline after an anonymous

20
hash.c
Просмотреть файл

@ -3138,23 +3138,21 @@ static VALUE
env_select(VALUE ehash)
{
VALUE result;
char **env;
VALUE keys;
long i;
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
result = rb_hash_new();
env = GET_ENVIRON(environ);
while (*env) {
char *s = strchr(*env, '=');
if (s) {
VALUE k = env_str_new(*env, s-*env);
VALUE v = env_str_new2(s+1);
if (RTEST(rb_yield_values(2, k, v))) {
rb_hash_aset(result, k, v);
keys = env_keys();
for (i = 0; i < RARRAY_LEN(keys); ++i) {
VALUE key = RARRAY_AREF(keys, i);
VALUE val = rb_f_getenv(Qnil, key);
if (!NIL_P(val)) {
if (RTEST(rb_yield_values(2, key, val))) {
rb_hash_aset(result, key, val);
}
}
env++;
}
FREE_ENVIRON(environ);
return result;
}

Просмотреть файл

@ -517,4 +517,20 @@ class TestEnv < Test::Unit::TestCase
v = (ENV[k] = 'bar'*5000 rescue 'bar'*1500)
end;
end
def test_memory_leak_select
bug9978 = '[ruby-dev:48325] [Bug #9978]'
assert_no_memory_leak([], <<-'end;', "5_000.times {ENV.select {break}}", bug9978)
ENV.clear
k = 'FOO'
(ENV[k] = 'bar'*5000 rescue 'bar'*1500)
end;
end
def test_memory_crash_select
assert_normal_exit(<<-'end;')
1000.times {ENV["FOO#{i}"] = 'bar'}
ENV.select {ENV.clear}
end;
end
end