[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]