summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--hash.c29
-rw-r--r--test/ruby/test_env.rb12
-rw-r--r--test/ruby/test_require.rb15
4 files changed, 43 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index ab3a452684..b17eec524b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Sep 11 16:47:41 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * hash.c (ruby_setenv): raise if putenv and SetEnvironmentVariable
+ failed, because of the restriction of the size on Windows.
+ based on a patch from Peter Weldon at [ruby-core:32304]. fix:
+ Bug#3812, [ruby-core:32250]
+
Sat Sep 11 15:19:57 2010 Eric Hodel <drbrain@segment7.net>
* lib/webrick/httpauth/digestauth.rb (WEBrick::Config::DigestAuth):
diff --git a/hash.c b/hash.c
index 8bba586dfb..73f90125f9 100644
--- a/hash.c
+++ b/hash.c
@@ -2139,29 +2139,28 @@ void
ruby_setenv(const char *name, const char *value)
{
#if defined(_WIN32)
- int len;
- char *buf;
+ VALUE buf;
+ int failed = 0;
if (strchr(name, '=')) {
+ fail:
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);
+ buf = rb_sprintf("%s=%s", name, value);
}
else {
- len = strlen(name) + 1 + 1;
- buf = ALLOCA_N(char, len);
- snprintf(buf, len, "%s=", name);
- putenv(buf);
- SetEnvironmentVariable(name, 0);
+ buf = rb_sprintf("%s=", name);
+ }
+ failed = putenv(RSTRING_PTR(buf));
+ /* even if putenv() failed, clean up and try to delete the
+ * variable from the system area. */
+ rb_str_resize(buf, 0);
+ if (!value || !*value) {
+ /* putenv() doesn't handle empty value */
+ if (!SetEnvironmentVariable(name,value)) goto fail;
}
+ if (failed) goto fail;
#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 785b6bb067..97bf8fa476 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -374,4 +374,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 /mswin|mingw/ =~ RUBY_PLATFORM
+ 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
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index f87de90ab9..aef7f7b527 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -29,7 +29,7 @@ class TestRequire < Test::Unit::TestCase
INPUT
begin
- assert_in_out_err(["-S", "foo/" * 10000 + "foo"], "") do |r, e|
+ assert_in_out_err(["-S", "foo/" * 2500 + "foo"], "") do |r, e|
assert_equal([], r)
assert_operator(2, :<=, e.size)
assert_equal("openpath: pathname too long (ignored)", e.first)
@@ -48,19 +48,24 @@ class TestRequire < Test::Unit::TestCase
def test_require_path_home
env_rubypath, env_home = ENV["RUBYPATH"], ENV["HOME"]
+ pathname_too_long = /pathname too long \(ignored\).*\(LoadError\)/m
ENV["RUBYPATH"] = "~"
- ENV["HOME"] = "/foo" * 10000
- assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+ ENV["HOME"] = "/foo" * 2500
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], pathname_too_long)
- ENV["RUBYPATH"] = "~" + "/foo" * 10000
+ ENV["RUBYPATH"] = "~" + "/foo" * 2500
ENV["HOME"] = "/foo"
- assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], pathname_too_long)
t = Tempfile.new(["test_ruby_test_require", ".rb"])
t.puts "p :ok"
t.close
+
ENV["RUBYPATH"] = "~"
+ ENV["HOME"] = t.path
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], /\(LoadError\)/)
+
ENV["HOME"], name = File.split(t.path)
assert_in_out_err(["-S", name], "", %w(:ok), [])