From a2401333fad1594392991fc482ddbcb903331ec7 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Wed, 10 Jun 2020 20:45:28 -0400 Subject: [PATCH] 8246042: Non-ASCII characters are not handled correctly in the native launcher Reviewed-by: herrick, almatvee --- .../share/native/applauncher/JvmLauncher.cpp | 12 ++++ .../share/native/applauncher/JvmLauncher.h | 4 +- .../share/native/common/tstrings.cpp | 4 ++ .../share/native/common/tstrings.h | 3 + test/jdk/tools/jpackage/apps/image/Hello.java | 5 ++ .../jdk/jpackage/tests/UnicodeArgsTest.java | 70 +++++++++++++++++++ 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp index 8115cead584..1941d39a6aa 100644 --- a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp +++ b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp @@ -169,7 +169,19 @@ void Jvm::launch() { jint ergo); std::vector argv; +#ifdef TSTRINGS_WITH_WCHAR + std::vector mbcs_args; + do { + tstring_array::const_iterator it = args.begin(); + const tstring_array::const_iterator end = args.end(); + for (; it != end; ++it) { + mbcs_args.push_back(tstrings::toACP(*it)); + } + } while (0); + convertArgs(mbcs_args, argv); +#else convertArgs(args, argv); +#endif // Don't count terminal '0'. const int argc = (int)argv.size() - 1; diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h index cffc0bac95d..096d5688c4c 100644 --- a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h +++ b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h @@ -37,7 +37,7 @@ class Jvm { Jvm& initFromConfigFile(const CfgFile& cfgFile); Jvm& addArgument(const tstring& value) { - args.push_back(tstrings::any(value).str()); + args.push_back(value); return *this; } @@ -54,7 +54,7 @@ class Jvm { private: tstring jvmPath; - std::vector args; + tstring_array args; }; #endif // JvmLauncher_h diff --git a/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp b/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp index 0bbba1672f8..0efad4191bd 100644 --- a/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp +++ b/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp @@ -275,6 +275,10 @@ std::wstring fromMultiByte(const std::string& str, int encoding) { } } // namespace +std::string toACP(const std::wstring& utf16str) { + return toMultiByte(utf16str, CP_ACP); +} + std::string toUtf8(const std::wstring& utf16str) { return toMultiByte(utf16str, CP_UTF8); } diff --git a/src/jdk.incubator.jpackage/share/native/common/tstrings.h b/src/jdk.incubator.jpackage/share/native/common/tstrings.h index a3facf9d2b1..295fb4e68ca 100644 --- a/src/jdk.incubator.jpackage/share/native/common/tstrings.h +++ b/src/jdk.incubator.jpackage/share/native/common/tstrings.h @@ -140,6 +140,9 @@ namespace tstrings { } #ifdef TSTRINGS_WITH_WCHAR + // conversion to the active code page + std::string toACP(const std::wstring& utf16str); + // conversion to Utf8 std::string toUtf8(const std::wstring& utf16str); diff --git a/test/jdk/tools/jpackage/apps/image/Hello.java b/test/jdk/tools/jpackage/apps/image/Hello.java index 2e81ca64ecc..a7cf915e318 100644 --- a/test/jdk/tools/jpackage/apps/image/Hello.java +++ b/test/jdk/tools/jpackage/apps/image/Hello.java @@ -50,6 +50,11 @@ public static void main(String[] args) throws IOException, InterruptedException var lines = printArgs(args); + Stream.of(args).forEach(arg -> System.out.println( + arg.codePoints() + .mapToObj(codePoint -> String.format("0x%04x", codePoint)) + .collect(Collectors.joining(",", "[", "]")))); + lines.forEach(System.out::println); var outputFile = getOutputFile(args); diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java new file mode 100644 index 00000000000..cd37e7ae6e3 --- /dev/null +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.tests; + +import java.util.stream.Collectors; +import jdk.jpackage.test.TKit; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.HelloApp; +import jdk.jpackage.test.JPackageCommand; + +/* + * @test + * @summary test how app launcher handles unicode command line arguments + * @library ../../../../helpers + * @build jdk.jpackage.test.* + * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @compile UnicodeArgsTest.java + * @requires (os.family == "windows") + * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main + * --jpt-run=jdk.jpackage.tests.UnicodeArgsTest + */ + +public final class UnicodeArgsTest { + + @Parameter("true") + @Parameter("false") + @Test + public void test8246042(boolean onCommandLine) { + final String testString = new String(Character.toChars(0x00E9)); + + TKit.trace(String.format("Test string code points: %s", testString + .codePoints() + .mapToObj(codePoint -> String.format("0x%04x", codePoint)) + .collect(Collectors.joining(",", "[", "]")))); + + JPackageCommand cmd = JPackageCommand.helloAppImage().useToolProvider(true); + if (!onCommandLine) { + cmd.addArguments("--arguments", testString); + } + cmd.executeAndAssertImageCreated(); + + if (onCommandLine) { + HelloApp.executeLauncherAndVerifyOutput(cmd, testString); + } else { + HelloApp.executeLauncherAndVerifyOutput(cmd); + } + } +}