8132379: -J options can cause crash or "Warning: app args parsing error passing arguments as-is"
authorhenryjen
Thu, 07 Jul 2016 21:15:24 -0700
changeset 39640 6f1a839ff43d
parent 39639 b2d7ac2be69e
child 39641 8769812a294f
8132379: -J options can cause crash or "Warning: app args parsing error passing arguments as-is" Reviewed-by: ksrini
jdk/src/java.base/share/native/libjli/args.c
jdk/src/java.base/windows/native/libjli/java_md.c
jdk/test/tools/launcher/Arrrghs.java
--- a/jdk/src/java.base/share/native/libjli/args.c	Wed Jul 13 14:56:00 2016 +0100
+++ b/jdk/src/java.base/share/native/libjli/args.c	Thu Jul 07 21:15:24 2016 -0700
@@ -130,7 +130,7 @@
         expectingNoDashArg = JNI_FALSE;
     }
     // only update on java mode and not yet found main class
-    if (firstAppArgIndex == -1 && idx != 0) {
+    if (firstAppArgIndex == NOT_FOUND && idx != 0) {
         firstAppArgIndex = (int) idx;
     }
 }
--- a/jdk/src/java.base/windows/native/libjli/java_md.c	Wed Jul 13 14:56:00 2016 +0100
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c	Thu Jul 07 21:15:24 2016 -0700
@@ -943,26 +943,6 @@
     return JNI_FALSE;
 }
 
-int
-filterArgs(StdArg *stdargs, const int nargc, StdArg **pargv) {
-    StdArg* argv = NULL;
-    int nargs = 0;
-    int i;
-
-    /* Copy the non-vm args */
-    for (i = 0; i < nargc ; i++) {
-        const char *arg = stdargs[i].arg;
-        if (arg[0] == '-' && arg[1] == 'J')
-            continue;
-        argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg));
-        argv[nargs].arg = JLI_StringDup(arg);
-        argv[nargs].has_wildcard = stdargs[i].has_wildcard;
-        nargs++;
-    }
-    *pargv = argv;
-    return nargs;
-}
-
 /*
  * At this point we have the arguments to the application, and we need to
  * check with original stdargs in order to compare which of these truly
@@ -975,12 +955,13 @@
     int i, j, idx;
     size_t tlen;
     jobjectArray outArray, inArray;
-    char *ostart, *astart, **nargv;
+    char *arg, **nargv;
     jboolean needs_expansion = JNI_FALSE;
     jmethodID mid;
-    int filteredargc, stdargc;
+    int stdargc;
     StdArg *stdargs;
-    StdArg *filteredargs;
+    int *appArgIdx;
+    int isTool;
     jclass cls = GetLauncherHelperClass(env);
     NULL_CHECK0(cls);
 
@@ -991,8 +972,6 @@
     stdargs = JLI_GetStdArgs();
     stdargc = JLI_GetStdArgc();
 
-    filteredargc = filterArgs(stdargs, stdargc, &filteredargs);
-
     // sanity check, this should never happen
     if (argc > stdargc) {
         JLI_TraceLauncher("Warning: app args is larger than the original, %d %d\n", argc, stdargc);
@@ -1001,22 +980,35 @@
     }
 
     // sanity check, match the args we have, to the holy grail
-    idx = filteredargc - argc;
-    ostart = filteredargs[idx].arg;
-    astart = strv[0];
-    // sanity check, ensure that the first argument of the arrays are the same
-    if (JLI_StrCmp(ostart, astart) != 0) {
-        // some thing is amiss the args don't match
-        JLI_TraceLauncher("Warning: app args parsing error\n");
-        JLI_TraceLauncher("passing arguments as-is\n");
+    idx = JLI_GetAppArgIndex();
+    isTool = (idx == 0);
+    if (isTool) { idx++; } // skip tool name
+    JLI_TraceLauncher("AppArgIndex: %d points to %s\n", idx, stdargs[idx].arg);
+
+    appArgIdx = calloc(argc, sizeof(int));
+    for (i = idx, j = 0; i < stdargc; i++) {
+        if (isTool) { // filter -J used by tools to pass JVM options
+            arg = stdargs[i].arg;
+            if (arg[0] == '-' && arg[1] == 'J') {
+                continue;
+            }
+        }
+        appArgIdx[j++] = i;
+    }
+    // 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);
     }
 
     // make a copy of the args which will be expanded in java if required.
     nargv = (char **)JLI_MemAlloc(argc * sizeof(char*));
-    for (i = 0, j = idx; i < argc; i++, j++) {
-        jboolean arg_expand = (JLI_StrCmp(filteredargs[j].arg, strv[i]) == 0)
-                                ? filteredargs[j].has_wildcard
+    for (i = 0; i < argc; i++) {
+        j = appArgIdx[i];
+        jboolean arg_expand = (JLI_StrCmp(stdargs[j].arg, strv[i]) == 0)
+                                ? stdargs[j].has_wildcard
                                 : JNI_FALSE;
         if (needs_expansion == JNI_FALSE)
             needs_expansion = arg_expand;
@@ -1039,6 +1031,7 @@
             JLI_MemFree(nargv[i]);
         }
         JLI_MemFree(nargv);
+        JLI_MemFree(appArgIdx);
         return NewPlatformStringArray(env, strv, argc);
     }
     NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
@@ -1053,6 +1046,6 @@
         JLI_MemFree(nargv[i]);
     }
     JLI_MemFree(nargv);
-    JLI_MemFree(filteredargs);
+    JLI_MemFree(appArgIdx);
     return outArray;
 }
--- a/jdk/test/tools/launcher/Arrrghs.java	Wed Jul 13 14:56:00 2016 +0100
+++ b/jdk/test/tools/launcher/Arrrghs.java	Thu Jul 07 21:15:24 2016 -0700
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- *      6894719 6968053 7151434 7146424 8007333 8077822 8143640
+ *      6894719 6968053 7151434 7146424 8007333 8077822 8143640 8132379
  * @summary Argument parsing validation.
  * @compile -XDignore.symbol.file Arrrghs.java
  * @run main/othervm Arrrghs
@@ -383,6 +383,12 @@
         checkArgumentWildcard("empty\\*?", "empty\\*?");
         checkArgumentWildcard("empty\\?*", "empty\\?*");
 
+        // 8132379: java should not filter out -J options for application
+        String[] args = { "-J-one", "-Jtwo", "lib\\???.java", "-J-Dsomething",
+           "a", "-J-Dlast.arg" };
+        String[] expected = { "-J-one", "-Jtwo", "lib\\Fbo.java",
+           "lib\\Foo.java", "-J-Dsomething", "a", "-J-Dlast.arg" };
+        checkArgumentWildcard(args, expected);
     }
 
     void doArgumentCheck(String inArgs, String... expArgs) {