changeset 59727:9c238ccfdb27

8246042: Non-ASCII characters are not handled correctly in the native launcher Reviewed-by: herrick, almatvee
author asemenyuk
date Wed, 10 Jun 2020 20:45:28 -0400
parents c62986f0ae6b
children 36a2f799b7fb
files src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h src/jdk.incubator.jpackage/share/native/common/tstrings.cpp src/jdk.incubator.jpackage/share/native/common/tstrings.h test/jdk/tools/jpackage/apps/image/Hello.java test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java
diffstat 6 files changed, 96 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp	Wed Jun 10 20:45:28 2020 -0400
+++ b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp	Wed Jun 10 20:45:28 2020 -0400
@@ -169,7 +169,19 @@
         jint ergo);
 
     std::vector<char*> argv;
+#ifdef TSTRINGS_WITH_WCHAR
+    std::vector<std::string> 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;
--- a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h	Wed Jun 10 20:45:28 2020 -0400
+++ b/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h	Wed Jun 10 20:45:28 2020 -0400
@@ -37,7 +37,7 @@
     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 @@
 
 private:
     tstring jvmPath;
-    std::vector<std::string> args;
+    tstring_array args;
 };
 
 #endif // JvmLauncher_h
--- a/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp	Wed Jun 10 20:45:28 2020 -0400
+++ b/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp	Wed Jun 10 20:45:28 2020 -0400
@@ -275,6 +275,10 @@
 }
 } // 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);
 }
--- a/src/jdk.incubator.jpackage/share/native/common/tstrings.h	Wed Jun 10 20:45:28 2020 -0400
+++ b/src/jdk.incubator.jpackage/share/native/common/tstrings.h	Wed Jun 10 20:45:28 2020 -0400
@@ -140,6 +140,9 @@
     }
 
 #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);
 
--- a/test/jdk/tools/jpackage/apps/image/Hello.java	Wed Jun 10 20:45:28 2020 -0400
+++ b/test/jdk/tools/jpackage/apps/image/Hello.java	Wed Jun 10 20:45:28 2020 -0400
@@ -50,6 +50,11 @@
 
         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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java	Wed Jun 10 20:45:28 2020 -0400
@@ -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);
+        }
+    }
+}