From 4aff4706ff0b54a3d5cd80cef3daaea3751b0884 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C4=81vis=20Mos=C4=81ns?= <davispuh@gmail.com>
Date: Wed, 3 Aug 2016 00:16:40 +0300
Subject: [PATCH] Always use UTF-8 encoded environment on Windows

---
 hash.c                 | 26 +++-----------------------
 include/ruby/win32.h   |  2 +-
 test/ruby/test_env.rb  | 16 +++++++---------
 test/ruby/test_m17n.rb | 10 +++++++---
 4 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/hash.c b/hash.c
index 963d9ae..42097e7 100644
--- a/hash.c
+++ b/hash.c
@@ -2896,18 +2896,7 @@ static char **my_environ;
 #undef environ
 #define environ my_environ
 #undef getenv
-static inline char *
-w32_getenv(const char *name)
-{
-    static int binary = -1;
-    static int locale = -1;
-    if (binary < 0) {
-	binary = rb_ascii8bit_encindex();
-	locale = rb_locale_encindex();
-    }
-    return locale == binary ? rb_w32_getenv(name) : rb_w32_ugetenv(name);
-}
-#define getenv(n) w32_getenv(n)
+#define getenv(n) rb_w32_ugetenv(n)
 #elif defined(__APPLE__)
 #undef environ
 #define environ (*_NSGetEnviron())
@@ -2926,20 +2915,11 @@ extern char **environ;
 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
 #endif
 
-#ifdef _WIN32
-static VALUE
-env_str_transcode(VALUE str, rb_encoding *enc)
-{
-    return rb_str_conv_enc_opts(str, NULL, enc,
-				ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE, Qnil);
-}
-#endif
-
 static VALUE
 env_str_new(const char *ptr, long len)
 {
 #ifdef _WIN32
-    VALUE str = env_str_transcode(rb_utf8_str_new(ptr, len), rb_locale_encoding());
+    VALUE str = rb_utf8_str_new(ptr, len);
 #else
     VALUE str = rb_locale_str_new(ptr, len);
 #endif
@@ -2952,7 +2932,7 @@ static VALUE
 env_path_str_new(const char *ptr)
 {
 #ifdef _WIN32
-    VALUE str = env_str_transcode(rb_utf8_str_new_cstr(ptr), rb_filesystem_encoding());
+    VALUE str = rb_utf8_str_new_cstr(ptr);
 #else
     VALUE str = rb_filesystem_str_new_cstr(ptr);
 #endif
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index 68b8db7..37579b0 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -695,7 +695,7 @@ extern char *rb_w32_strerror(int);
 #define getcwd(b, s)		rb_w32_getcwd(b, s)
 
 #undef getenv
-#define getenv(n)		rb_w32_getenv(n)
+#define getenv(n)		rb_w32_ugetenv(n)
 
 #undef rename
 #define rename(o, n)		rb_w32_rename(o, n)
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index 17323cc..4517c85 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -510,15 +510,13 @@ def test_memory_leak_shift
       end;
     end
 
-    if Encoding.find("locale") == Encoding::UTF_8
-      def test_utf8
-        text = "testing \u{e5 e1 e2 e4 e3 101 3042}"
-        test = ENV["test"]
-        ENV["test"] = text
-        assert_equal text, ENV["test"]
-      ensure
-        ENV["test"] = test
-      end
+    def test_utf8
+      text = "testing \u{e5 e1 e2 e4 e3 101 3042}"
+      test = ENV["test"]
+      ENV["test"] = text
+      assert_equal text, ENV["test"]
+    ensure
+      ENV["test"] = test
     end
   end
 end
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index 950d205..4310e16 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1312,10 +1312,14 @@ def test_marshal
   end
 
   def test_env
-    locale_encoding = Encoding.find("locale")
+    if RUBY_PLATFORM =~ /bccwin|mswin|mingw/
+      env_encoding = Encoding::UTF_8
+    else
+      env_encoding = Encoding.find("locale")
+    end
     ENV.each {|k, v|
-      assert_equal(locale_encoding, k.encoding, k)
-      assert_equal(locale_encoding, v.encoding, v)
+      assert_equal(env_encoding, k.encoding, k)
+      assert_equal(env_encoding, v.encoding, v)
     }
   end
 
-- 
2.9.2

