Skip to content

Commit a837a30

Browse files
ryanmeiera-maurice
authored andcommitted
Allow generate_xml_from_google_services to handle unicode characters in filepath on Windows.
Tested on Windows and MacOS with Unity 2018.2 PiperOrigin-RevId: 252919140
1 parent f82aaad commit a837a30

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed
341 KB
Binary file not shown.

generate_xml_from_google_services_json.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
__author__ = 'Wouter van Oortmerssen'
2424

2525
import argparse
26+
import ctypes
2627
import json
2728
import os
29+
import platform
2830
import sys
2931
from xml.etree import ElementTree
3032

@@ -218,6 +220,33 @@ def indent(elem, level=0):
218220
elem.tail = i
219221

220222

223+
def argv_as_unicode_win32():
224+
"""Returns unicode command line arguments on windows.
225+
"""
226+
227+
get_command_line_w = ctypes.cdll.kernel32.GetCommandLineW
228+
get_command_line_w.restype = ctypes.wintypes.LPCWSTR
229+
230+
# CommandLineToArgvW parses the Unicode command line
231+
command_line_to_argv_w = ctypes.windll.shell32.CommandLineToArgvW
232+
command_line_to_argv_w.argtypes = [
233+
ctypes.wintypes.LPCWSTR,
234+
ctypes.wintypes.POINTER(ctypes.wintypes.c_int)
235+
]
236+
command_line_to_argv_w.restype = ctypes.wintypes.POINTER(
237+
ctypes.wintypes.LPWSTR)
238+
239+
argc = ctypes.wintypes.c_int(0)
240+
argv = command_line_to_argv_w(get_command_line_w(), argc)
241+
242+
# Strip the python executable from the arguments if it exists
243+
# (It would be listed as the first argument on the windows command line, but
244+
# not in the arguments to the python script)
245+
sys_argv_len = len(sys.argv)
246+
return [unicode(argv[i]) for i in
247+
range(argc.value - sys_argv_len, argc.value)]
248+
249+
221250
def main():
222251
parser = argparse.ArgumentParser(
223252
description=((
@@ -254,6 +283,11 @@ def main():
254283
default=False,
255284
required=False)
256285

286+
# python 2 on Windows doesn't handle unicode arguments well, so we need to
287+
# pre-process the command line arguments before trying to parse them.
288+
if platform.system() == 'Windows':
289+
sys.argv = argv_as_unicode_win32()
290+
257291
args = parser.parse_args()
258292

259293
if args.plist:
@@ -264,12 +298,18 @@ def main():
264298
output_filename = DEFAULT_OUTPUT_FILENAME
265299

266300
if args.i:
267-
input_filename = args.i
301+
input_filename_raw = args.i
302+
# Encode the input string (type unicode) as a normal string (type str)
303+
# using the 'utf-8' encoding so that it can be worked with the same as
304+
# input names from other sources (like the defaults).
305+
input_filename = input_filename_raw.encode('utf-8')
268306

269307
if args.o:
270308
output_filename = args.o
271309

272-
with open(input_filename, 'r') as ifile:
310+
# Decode the filename to a unicode string using the 'utf-8' encoding to
311+
# properly handle filepaths with unicode characters in them.
312+
with open(input_filename.decode('utf-8'), 'r') as ifile:
273313
file_string = ifile.read()
274314

275315
json_string = None
@@ -387,7 +427,9 @@ def main():
387427
if args.l:
388428
for package in packages:
389429
if package:
390-
sys.stdout.write(package + '\n')
430+
# Encode the output string in case the system's default encoding differs
431+
# from the encoding of the string being printed.
432+
sys.stdout.write((package + '\n').encode(sys.getdefaultencoding()))
391433
else:
392434
path = os.path.dirname(output_filename)
393435

0 commit comments

Comments
 (0)