ruby-changes:17225
From: nobu <ko1@a...>
Date: Sat, 11 Sep 2010 16:47:52 +0900 (JST)
Subject: [ruby-changes:17225] Ruby:r29225 (trunk): * hash.c (ruby_setenv): raise if putenv and SetEnvironmentVariable
nobu 2010-09-11 16:47:44 +0900 (Sat, 11 Sep 2010) New Revision: 29225 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29225 Log: * 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] Modified files: trunk/ChangeLog trunk/hash.c trunk/test/ruby/test_env.rb trunk/test/ruby/test_require.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 29224) +++ ChangeLog (revision 29225) @@ -1,3 +1,10 @@ +Sat Sep 11 16:47:41 2010 Nobuyoshi Nakada <nobu@r...> + + * 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@s...> * lib/webrick/httpauth/digestauth.rb (WEBrick::Config::DigestAuth): Index: hash.c =================================================================== --- hash.c (revision 29224) +++ hash.c (revision 29225) @@ -2139,29 +2139,28 @@ 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 Index: test/ruby/test_require.rb =================================================================== --- test/ruby/test_require.rb (revision 29224) +++ test/ruby/test_require.rb (revision 29225) @@ -29,7 +29,7 @@ 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 @@ 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), []) Index: test/ruby/test_env.rb =================================================================== --- test/ruby/test_env.rb (revision 29224) +++ test/ruby/test_env.rb (revision 29225) @@ -374,4 +374,16 @@ 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/