Skip to content

Commit f91bd16

Browse files
committed
merge revision(s) r46557,r46565: [Backport ruby#9978]
* 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 ruby#9978] keys array first instead of iterating on environ directly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47054 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 6508fff commit f91bd16

File tree

4 files changed

+32
-12
lines changed

4 files changed

+32
-12
lines changed

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Mon Aug 4 01:26:46 2014 Nobuyoshi Nakada <[email protected]>
2+
3+
* hash.c (env_select): fix memory leak and crash on Windows, make
4+
keys array first instead of iterating on environ directly.
5+
[ruby-dev:48325] [Bug #9978]
6+
17
Mon Aug 4 01:24:09 2014 Nobuyoshi Nakada <[email protected]>
28

39
* hash.c (ruby_setenv): fix memory leak on Windows, free

hash.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,23 +3139,21 @@ static VALUE
31393139
env_select(VALUE ehash)
31403140
{
31413141
VALUE result;
3142-
char **env;
3142+
VALUE keys;
3143+
long i;
31433144

31443145
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
31453146
result = rb_hash_new();
3146-
env = GET_ENVIRON(environ);
3147-
while (*env) {
3148-
char *s = strchr(*env, '=');
3149-
if (s) {
3150-
VALUE k = env_str_new(*env, s-*env);
3151-
VALUE v = env_str_new2(s+1);
3152-
if (RTEST(rb_yield_values(2, k, v))) {
3153-
rb_hash_aset(result, k, v);
3147+
keys = env_keys();
3148+
for (i = 0; i < RARRAY_LEN(keys); ++i) {
3149+
VALUE key = RARRAY_AREF(keys, i);
3150+
VALUE val = rb_f_getenv(Qnil, key);
3151+
if (!NIL_P(val)) {
3152+
if (RTEST(rb_yield_values(2, key, val))) {
3153+
rb_hash_aset(result, key, val);
31543154
}
31553155
}
3156-
env++;
31573156
}
3158-
FREE_ENVIRON(environ);
31593157

31603158
return result;
31613159
}

test/ruby/test_env.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,4 +418,20 @@ def test_memory_leak_aset
418418
v = (ENV[k] = 'bar'*5000 rescue 'bar'*1500)
419419
end;
420420
end
421+
422+
def test_memory_leak_select
423+
bug9978 = '[ruby-dev:48325] [Bug #9978]'
424+
assert_no_memory_leak([], <<-'end;', "5_000.times {ENV.select {break}}", bug9978)
425+
ENV.clear
426+
k = 'FOO'
427+
(ENV[k] = 'bar'*5000 rescue 'bar'*1500)
428+
end;
429+
end
430+
431+
def test_memory_crash_select
432+
assert_normal_exit(<<-'end;')
433+
1000.times {ENV["FOO#{i}"] = 'bar'}
434+
ENV.select {ENV.clear}
435+
end;
436+
end
421437
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.1.2"
22
#define RUBY_RELEASE_DATE "2014-08-04"
3-
#define RUBY_PATCHLEVEL 192
3+
#define RUBY_PATCHLEVEL 193
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 8

0 commit comments

Comments
 (0)