summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-03 03:43:19 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-09-03 03:43:19 +0000
commit6ed3a3524a05dbd22cab4440dd81f7c76ea67afd (patch)
tree4aade8c63f72316022143d313bd9a0ee95c5f7b0 /hash.c
parentd910ce1f908a70afad5261d91fd6dec0a3708240 (diff)
merge revision(s) 46550,46557,46565,46570,46585,46595,46822: [Backport #9977] [Backport #9978] [Backport #9983]
* hash.c (ruby_setenv): fix memory leak on Windows, free environment strings block after check for the size. [ruby-dev:48323] [Bug #9977] * 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] keys array first instead of iterating on environ directly. * hash.c (env_shift): fix memory leak on Windows, free environment strings block always. [ruby-dev:48332] [Bug #9983] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@47365 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/hash.c b/hash.c
index 30aa03101e..1ca87de1ec 100644
--- a/hash.c
+++ b/hash.c
@@ -2416,9 +2416,12 @@ ruby_setenv(const char *name, const char *value)
rb_sys_fail("ruby_setenv");
}
if (value) {
- const char* p = GetEnvironmentStringsA();
+ char* p = GetEnvironmentStringsA();
+ size_t n;
if (!p) goto fail; /* never happen */
- if (strlen(name) + 2 + strlen(value) + getenvsize(p) >= getenvblocksize()) {
+ n = strlen(name) + 2 + strlen(value) + getenvsize(p);
+ FreeEnvironmentStringsA(p);
+ if (n >= getenvblocksize()) {
goto fail; /* 2 for '=' & '\0' */
}
buf = rb_sprintf("%s=%s", name, value);
@@ -2806,24 +2809,22 @@ static VALUE
env_select(VALUE ehash)
{
VALUE result;
- char **env;
+ VALUE keys;
+ long i;
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
rb_secure(4);
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_PTR(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;
}
@@ -3237,6 +3238,7 @@ static VALUE
env_shift(void)
{
char **env;
+ VALUE result = Qnil;
rb_secure(4);
env = GET_ENVIRON(environ);
@@ -3246,11 +3248,11 @@ env_shift(void)
VALUE key = env_str_new(*env, s-*env);
VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
env_delete(Qnil, key);
- return rb_assoc_new(key, val);
+ result = rb_assoc_new(key, val);
}
}
FREE_ENVIRON(environ);
- return Qnil;
+ return result;
}
/*