commit 03b9b99beaa55f38bac1ccb13c3b0c19ac461014 Author: Peter Weldon Date: Tue Sep 7 15:51:53 2010 -0700 hash.c (ruby_setenv): Add error checking for win32 diff --git a/hash.c b/hash.c index 8bba586..77301e4 100644 --- a/hash.c +++ b/hash.c @@ -2141,27 +2141,19 @@ ruby_setenv(const char *name, const char *value) #if defined(_WIN32) int len; char *buf; - if (strchr(name, '=')) { - errno = EINVAL; - rb_sys_fail("ruby_setenv"); - } - if (value) { - len = strlen(name) + 1 + strlen(value) + 1; - buf = ALLOCA_N(char, len); - snprintf(buf, len, "%s=%s", name, value); - putenv(buf); - - /* putenv() doesn't handle empty value */ - if (!*value) - SetEnvironmentVariable(name,value); - } - else { - len = strlen(name) + 1 + 1; - buf = ALLOCA_N(char, len); - snprintf(buf, len, "%s=", name); - putenv(buf); - SetEnvironmentVariable(name, 0); - } + const char *new_value = value ? value : ""; + if (strchr(name, '=')) goto fail; + len = strlen(name) + 1 + strlen(new_value) + 1; + buf = ALLOCA_N(char, len); + if (!buf) goto fail; + snprintf(buf, len, "%s=%s", name, new_value); + if (putenv(buf)) goto fail; + if ((!value || !*value) && !SetEnvironmentVariable(name,value)) + goto fail; + return; + fail: + errno = EINVAL; + rb_sys_fail("ruby_setenv"); #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV) #undef setenv #undef unsetenv diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb index 785b6bb..52b95e3 100644 --- a/test/ruby/test_env.rb +++ b/test/ruby/test_env.rb @@ -1,4 +1,5 @@ require 'test/unit' +require 'rbconfig' class TestEnv < Test::Unit::TestCase IGNORE_CASE = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM @@ -374,4 +375,16 @@ class TestEnv < Test::Unit::TestCase ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| v1 ? k + "_" + v1 + "_" + v2 : v2 } check(ENV.to_hash.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)]) end + + def test_huge_value + huge_value = "bar" * 40960 + ENV["foo"] = "bar" + if Config::CONFIG['host_os'] =~ /mswin|mingw/ + assert_raise(Errno::EINVAL) { ENV["foo"] = huge_value } + assert_equal("bar", ENV["foo"]) + else + assert_nothing_raised { ENV["foo"] = huge_value } + assert_equal(huge_value, ENV["foo"]) + end + end end