Bug 1152428 - [mozprocess] Fix UnicodeEncodeError when non-ascii characters are in the environment, r?wlach
MozReview-Commit-ID: 3AG9oLxWexy
--- a/testing/mozbase/mozprocess/mozprocess/processhandler.py
+++ b/testing/mozbase/mozprocess/mozprocess/processhandler.py
@@ -92,26 +92,16 @@ class ProcessHandlerMixin(object):
# Set the process group id for linux systems
# Sets process group id to the pid of the parent process
# NOTE: This prevents you from using preexec_fn and managing
# child processes, TODO: Ideally, find a way around this
def setpgidfn():
os.setpgid(0, 0)
preexec_fn = setpgidfn
- if isinstance(env, dict):
- tmp_env = {}
- for k, v in env.iteritems():
- if isinstance(k, bytes):
- k = k.decode(sys.getfilesystemencoding() or 'utf-8', 'replace')
- if isinstance(v, bytes):
- v = v.decode(sys.getfilesystemencoding() or 'utf-8', 'replace')
- tmp_env[k] = v
- env = tmp_env
-
try:
subprocess.Popen.__init__(self, args, bufsize, executable,
stdin, stdout, stderr,
preexec_fn, close_fds,
shell, cwd, env,
universal_newlines, startupinfo, creationflags)
except OSError:
print >> sys.stderr, args
--- a/testing/mozbase/mozprocess/mozprocess/winprocess.py
+++ b/testing/mozbase/mozprocess/mozprocess/winprocess.py
@@ -29,17 +29,19 @@
# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-from __future__ import absolute_import
+from __future__ import absolute_import, unicode_literals
+
+import sys
from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFUNCTYPE, c_ulong
from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LPCWSTR, LPWSTR, UINT, WORD
from .qijo import QueryInformationJobObject
LPVOID = c_void_p
LPBYTE = POINTER(BYTE)
LPDWORD = POINTER(DWORD)
@@ -132,22 +134,28 @@ STARTF_FORCEOFFFEEDBACK = 0x80
STARTF_USESTDHANDLES = 0x100
# EnvironmentBlock
class EnvironmentBlock:
"""An object which can be passed as the lpEnv parameter of CreateProcess.
It is initialized with a dictionary."""
- def __init__(self, dict):
- if not dict:
+ def __init__(self, env):
+ if not env:
self._as_parameter_ = None
else:
- values = ["%s=%s" % (key, value)
- for (key, value) in dict.iteritems()]
+ values = []
+ fs_encoding = sys.getfilesystemencoding() or 'mbcs'
+ for k, v in env.iteritems():
+ if isinstance(k, bytes):
+ k = k.decode(fs_encoding, 'replace')
+ if isinstance(v, bytes):
+ v = v.decode(fs_encoding, 'replace')
+ values.append("{}={}".format(k, v))
values.append("")
self._as_parameter_ = LPCWSTR("\0".join(values))
# Error Messages we need to watch for go here
# See: http://msdn.microsoft.com/en-us/library/ms681388%28v=vs.85%29.aspx
ERROR_ABANDONED_WAIT_0 = 735
# GetLastError()
--- a/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py
+++ b/testing/mozbase/mozprocess/tests/test_mozprocess_misc.py
@@ -1,9 +1,10 @@
#!/usr/bin/env python
+# -*- coding: utf-8 -*-
import os
import unittest
import proctest
from mozprocess import processhandler
here = os.path.dirname(os.path.abspath(__file__))
@@ -19,10 +20,21 @@ class ProcTestMisc(proctest.ProcTest):
cwd=here)
p.run()
p.processOutput(timeout=5)
p.wait()
self.determine_status(p, False, ())
+ def test_unicode_in_environment(self):
+ env = {
+ 'FOOBAR': 'ʘ',
+ }
+ p = processhandler.ProcessHandler([self.python, self.proclaunch,
+ "process_normal_finish_python.ini"],
+ cwd=here, env=env)
+ # passes if no exceptions are raised
+ p.run()
+ p.wait()
+
if __name__ == '__main__':
unittest.main()