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

ruby-changes:38263

From: nobu <ko1@a...>
Date: Sun, 19 Apr 2015 10:43:21 +0900 (JST)
Subject: [ruby-changes:38263] nobu:r50344 (trunk): hash.c: check env vars encoding

nobu	2015-04-19 10:42:57 +0900 (Sun, 19 Apr 2015)

  New Revision: 50344

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50344

  Log:
    hash.c: check env vars encoding
    
    * hash.c (get_env_cstr): environment variables must be ASCII
      compatible, as dummy encodings and wide char encodings are
      unsupproted now.

  Modified files:
    trunk/ChangeLog
    trunk/hash.c
    trunk/test/ruby/test_env.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50343)
+++ ChangeLog	(revision 50344)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Apr 19 10:42:54 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* hash.c (get_env_cstr): environment variables must be ASCII
+	  compatible, as dummy encodings and wide char encodings are
+	  unsupproted now.
+
 Sat Apr 18 15:18:56 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/json/parser/parser.rl: raise with messages in UTF-8
Index: hash.c
===================================================================
--- hash.c	(revision 50343)
+++ hash.c	(revision 50344)
@@ -2699,9 +2699,24 @@ env_str_new2(const char *ptr) https://github.com/ruby/ruby/blob/trunk/hash.c#L2699
     return env_str_new(ptr, strlen(ptr));
 }
 
+static void *
+get_env_cstr(VALUE str, const char *name)
+{
+    char *var;
+    rb_encoding *enc = rb_enc_get(str);
+    if (!rb_enc_asciicompat(enc)) {
+	rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
+		 name, rb_enc_name(enc));
+    }
+    var = RSTRING_PTR(str);
+    if (memchr(var, '\0', RSTRING_LEN(str))) {
+	rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
+    }
+    return var;
+}
+
 #define get_env_ptr(var, val) \
-    (memchr((var = RSTRING_PTR(val)), '\0', RSTRING_LEN(val)) ? \
-     rb_raise(rb_eArgError, "bad environment variable " #var) : (void)0)
+    (var = get_env_cstr(val, #var))
 
 static inline const char *
 env_name(volatile VALUE *s)
Index: test/ruby/test_env.rb
===================================================================
--- test/ruby/test_env.rb	(revision 50343)
+++ test/ruby/test_env.rb	(revision 50344)
@@ -3,6 +3,23 @@ require 'test/unit' https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L3
 class TestEnv < Test::Unit::TestCase
   IGNORE_CASE = /bccwin|mswin|mingw/ =~ RUBY_PLATFORM
   PATH_ENV = "PATH"
+  INVALID_ENVVARS = [
+    "foo\0bar",
+    "\xa1\xa1".force_encoding(Encoding::UTF_16LE),
+    "foo".force_encoding(Encoding::ISO_2022_JP),
+  ]
+
+  def assert_invalid_env(msg = nil)
+    failed = {}
+    INVALID_ENVVARS.select do |v|
+      begin
+        assert_raise(ArgumentError) {yield v}
+      rescue MiniTest::Assertion => e
+        failed[v] = e
+      end
+    end
+    assert(failed.empty?, message(msg) {mu_pp(failed)})
+  end
 
   def setup
     @verbose = $VERBOSE
@@ -87,13 +104,13 @@ class TestEnv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L104
   end
 
   def test_delete
-    assert_raise(ArgumentError) { ENV.delete("foo\0bar") }
+    assert_invalid_env {|v| ENV.delete(v)}
     assert_nil(ENV.delete("TEST"))
     assert_nothing_raised { ENV.delete(PATH_ENV) }
   end
 
   def test_getenv
-    assert_raise(ArgumentError) { ENV["foo\0bar"] }
+    assert_invalid_env {|v| ENV[v]}
     ENV[PATH_ENV] = ""
     assert_equal("", ENV[PATH_ENV])
     assert_nil(ENV[""])
@@ -110,7 +127,7 @@ class TestEnv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L127
     assert_equal("foo", ENV.fetch("test", "foo"))
     assert_equal("bar", ENV.fetch("test") { "bar" })
     assert_equal("bar", ENV.fetch("test", "foo") { "bar" })
-    assert_raise(ArgumentError) { ENV.fetch("foo\0bar") }
+    assert_invalid_env {|v| ENV.fetch(v)}
     assert_nothing_raised { ENV.fetch(PATH_ENV, "foo") }
     ENV[PATH_ENV] = ""
     assert_equal("", ENV.fetch(PATH_ENV))
@@ -119,8 +136,8 @@ class TestEnv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L136
   def test_aset
     assert_nothing_raised { ENV["test"] = nil }
     assert_equal(nil, ENV["test"])
-    assert_raise(ArgumentError) { ENV["foo\0bar"] = "test" }
-    assert_raise(ArgumentError) { ENV["test"] = "foo\0bar" }
+    assert_invalid_env {|v| ENV[v] = "test"}
+    assert_invalid_env {|v| ENV["test"] = v}
 
     begin
       # setenv(3) allowed the name includes '=',
@@ -276,7 +293,7 @@ class TestEnv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L293
     assert_not_send([ENV, :has_key?, "test"])
     ENV["test"] = "foo"
     assert_send([ENV, :has_key?, "test"])
-    assert_raise(ArgumentError) { ENV.has_key?("foo\0bar") }
+    assert_invalid_env {|v| ENV.has_key?(v)}
   end
 
   def test_assoc
@@ -290,7 +307,7 @@ class TestEnv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_env.rb#L307
       assert_equal("test", k)
       assert_equal("foo", v)
     end
-    assert_raise(ArgumentError) { ENV.assoc("foo\0bar") }
+    assert_invalid_env {|v| ENV.assoc(v)}
   end
 
   def test_has_value2

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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