Hello core-libs-dev,

I'm a VM engineer at Microsoft and new to this mailing list. I took a look at 
JDK- 8234076 and the root cause is similar to a prior thread on a Windows 
launcher bug for JDK- 8231863, after the command line arguments are processed, 
the static variable firstAppArgIndex in 
src/java.base/share/native/libjli/args.c remains set to NOT_FOUND (-1). The 
reason for not finding a firstAppArgIndex in this case is because the command 
line supplied to the launcher has every argument prefixed with a dash, for 
example:

java --module-path=mods --module=com.greetings/com.greetings.Main --help

Because all arguments are prefixed with a dash, the checkArg function inside 
src/java.base/share/native/libjli/args.c never finds an app arg index.

Currently, this only causes an issue on Windows because of the custom argument 
expansion code in function CreateApplicationArgs  of 
src/java.base/windows/native/libjli/java_md.c. The code queries the 
firstAppArgIndex and proceeds to perform an array access without checking if 
the app index is greater or equal to 0, causing the randomly observed crash. 

I have made the following patch to address the issue:

--- a/src/java.base/windows/native/libjli/java_md.c
+++ b/src/java.base/windows/native/libjli/java_md.c
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 #include <wtypes.h>
 #include <commctrl.h>
+#include <assert.h>
 
 #include <jni.h>
 #include "java.h"
@@ -1015,6 +1016,17 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
 
     // sanity check, match the args we have, to the holy grail
     idx = JLI_GetAppArgIndex();
+
+    // First arg index is NOT_FOUND
+    if (idx < 0) {
+        // The only allowed value should be NOT_FOUND (-1) unless another 
change introduces 
+        // a different negative index
+        assert (idx == -1);
+        JLI_TraceLauncher("Warning: first app arg index not found, %d\n", idx);
+        JLI_TraceLauncher("passing arguments as-is.\n");
+        return NewPlatformStringArray(env, strv, argc);
+    }
+
     isTool = (idx == 0);
     if (isTool) { idx++; } // skip tool name
     JLI_TraceLauncher("AppArgIndex: %d points to %s\n", idx, stdargs[idx].arg);

I wanted to ask for an advice and opinion if this is the correct way to fix the 
problem?

I did few tests and I can confirm that the fix above doesn't change the current 
behaviour on Windows, because in case the negative index array access doesn't 
cause a crash, the later sanity check below (in java_md.c CreateApplicationArgs 
) will always catch the invalid case and simply pass down the arguments as is.

    // sanity check, ensure same number of arguments for application
    if (j != argc) {
        JLI_TraceLauncher("Warning: app args count doesn't match, %d %d\n", j, 
argc);
        JLI_TraceLauncher("passing arguments as-is.\n");
        JLI_MemFree(appArgIdx);
        return NewPlatformStringArray(env, strv, argc);
    }

However, if the command line is supplied with --module= instead of --module 
followed by a blank space, Windows will not perform argument expansion on the 
application arguments. For example:

java --module-path=mods --module=com.greetings/com.greetings.Main ./* --help 
(the path will not be expanded) 
java --module-path=mods --module com.greetings/com.greetings.Main ./* --help 
(the path will be correctly expanded)

I tested on Linux x86-64 and the argument expansion is correctly performed in 
both cases where --module= is used and where --module is followed by a space. 
Essentially, Windows behaves differently in this case, but it has always been 
this way. The patch only prevents the random crash, fixing the command line 
incompatibility will require a more substantial change. 

Please let me know if this approach is acceptable for the current bug report 
and I'll make a webrev and include appropriate launcher tests. I was thinking 
the tests should do extra validation on the output from _JAVA_LAUNCHER_DEBUG on 
Windows.

Thank you!
-Nikola

Reply via email to