From 136cbcc67f4e73c1c81b64ac2ffa9aab98a2e48f Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 22 Sep 2022 08:13:09 -0700 Subject: [PATCH] [Impeller] Convert the ImpellerC command line arguments to UTF-8 on Windows (flutter/engine#36335) --- .../ci/licenses_golden/licenses_flutter | 2 ++ engine/src/flutter/fml/BUILD.gn | 2 ++ engine/src/flutter/fml/command_line.h | 8 +++++ .../fml/platform/posix/command_line_posix.cc | 13 +++++++ .../fml/platform/win/command_line_win.cc | 35 +++++++++++++++++++ .../impeller/compiler/impellerc_main.cc | 8 +++-- 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 engine/src/flutter/fml/platform/posix/command_line_posix.cc create mode 100644 engine/src/flutter/fml/platform/win/command_line_win.cc diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index ad3ac0d3f54..2821a157992 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -335,6 +335,7 @@ FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h FILE: ../../../flutter/fml/platform/linux/paths_linux.cc FILE: ../../../flutter/fml/platform/linux/timerfd.cc FILE: ../../../flutter/fml/platform/linux/timerfd.h +FILE: ../../../flutter/fml/platform/posix/command_line_posix.cc FILE: ../../../flutter/fml/platform/posix/file_posix.cc FILE: ../../../flutter/fml/platform/posix/mapping_posix.cc FILE: ../../../flutter/fml/platform/posix/native_library_posix.cc @@ -342,6 +343,7 @@ FILE: ../../../flutter/fml/platform/posix/paths_posix.cc FILE: ../../../flutter/fml/platform/posix/posix_wrappers_posix.cc FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.cc FILE: ../../../flutter/fml/platform/posix/shared_mutex_posix.h +FILE: ../../../flutter/fml/platform/win/command_line_win.cc FILE: ../../../flutter/fml/platform/win/errors_win.cc FILE: ../../../flutter/fml/platform/win/errors_win.h FILE: ../../../flutter/fml/platform/win/file_win.cc diff --git a/engine/src/flutter/fml/BUILD.gn b/engine/src/flutter/fml/BUILD.gn index f7b5be3dc6a..3caa047f4b3 100644 --- a/engine/src/flutter/fml/BUILD.gn +++ b/engine/src/flutter/fml/BUILD.gn @@ -214,6 +214,7 @@ source_set("fml") { if (is_win) { sources += [ + "platform/win/command_line_win.cc", "platform/win/errors_win.cc", "platform/win/errors_win.h", "platform/win/file_win.cc", @@ -226,6 +227,7 @@ source_set("fml") { ] } else { sources += [ + "platform/posix/command_line_posix.cc", "platform/posix/file_posix.cc", "platform/posix/mapping_posix.cc", "platform/posix/native_library_posix.cc", diff --git a/engine/src/flutter/fml/command_line.h b/engine/src/flutter/fml/command_line.h index 75ec4fe7d73..c3f27803b9b 100644 --- a/engine/src/flutter/fml/command_line.h +++ b/engine/src/flutter/fml/command_line.h @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -239,6 +240,13 @@ inline CommandLine CommandLineFromInitializerList( // outlined at the top of this file. std::vector CommandLineToArgv(const CommandLine& command_line); +// Builds a |CommandLine| by obtaining the arguments of the process using host +// platform APIs. The resulting |CommandLine| will be encoded in UTF-8. +// Returns an empty optional if this is not supported on the host platform. +// +// This can be useful on platforms where argv may not be provided as UTF-8. +std::optional CommandLineFromPlatform(); + } // namespace fml #endif // LIB_FML_COMMAND_LINE_H_ diff --git a/engine/src/flutter/fml/platform/posix/command_line_posix.cc b/engine/src/flutter/fml/platform/posix/command_line_posix.cc new file mode 100644 index 00000000000..7f17ac1f3c9 --- /dev/null +++ b/engine/src/flutter/fml/platform/posix/command_line_posix.cc @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/fml/command_line.h" + +namespace fml { + +std::optional CommandLineFromPlatform() { + return std::nullopt; +} + +} // namespace fml diff --git a/engine/src/flutter/fml/platform/win/command_line_win.cc b/engine/src/flutter/fml/platform/win/command_line_win.cc new file mode 100644 index 00000000000..942f65e0721 --- /dev/null +++ b/engine/src/flutter/fml/platform/win/command_line_win.cc @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/fml/command_line.h" + +#include + +#include +#include + +namespace fml { + +std::optional CommandLineFromPlatform() { + wchar_t* command_line = GetCommandLineW(); + int unicode_argc; + std::unique_ptr unicode_argv( + CommandLineToArgvW(command_line, &unicode_argc), ::LocalFree); + if (!unicode_argv) { + return std::nullopt; + } + std::vector utf8_argv; + for (int i = 0; i < unicode_argc; ++i) { + wchar_t* arg = unicode_argv[i]; + int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, wcslen(arg), nullptr, 0, + nullptr, nullptr); + std::string utf8_arg(arg_len, 0); + WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg.data(), utf8_arg.size(), + nullptr, nullptr); + utf8_argv.push_back(std::move(utf8_arg)); + } + return CommandLineFromIterators(utf8_argv.begin(), utf8_argv.end()); +} + +} // namespace fml diff --git a/engine/src/flutter/impeller/compiler/impellerc_main.cc b/engine/src/flutter/impeller/compiler/impellerc_main.cc index b31b0d1610d..743441d4302 100644 --- a/engine/src/flutter/impeller/compiler/impellerc_main.cc +++ b/engine/src/flutter/impeller/compiler/impellerc_main.cc @@ -227,7 +227,9 @@ bool Main(const fml::CommandLine& command_line) { } // namespace impeller int main(int argc, char const* argv[]) { - return impeller::compiler::Main(fml::CommandLineFromArgcArgv(argc, argv)) - ? EXIT_SUCCESS - : EXIT_FAILURE; + std::optional command_line = fml::CommandLineFromPlatform(); + if (!command_line) { + command_line = fml::CommandLineFromArgcArgv(argc, argv); + } + return impeller::compiler::Main(*command_line) ? EXIT_SUCCESS : EXIT_FAILURE; }