1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-04-19 01:42:57 +00:00
parent 5c0df05b92
commit adfeb95c87
3 changed files with 47 additions and 9 deletions

View file

@ -1,3 +1,9 @@
Sun Apr 19 10:42:54 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org>
* ext/json/parser/parser.rl: raise with messages in UTF-8

19
hash.c
View file

@ -2699,9 +2699,24 @@ env_str_new2(const char *ptr)
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)

View file

@ -3,6 +3,23 @@ require 'test/unit'
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
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
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
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
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
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