--- a/src/java.base/share/native/libjli/args.c Tue Feb 13 15:28:07 2018 +0100
+++ b/src/java.base/share/native/libjli/args.c Mon Jun 11 11:23:20 2018 +0200
@@ -79,7 +79,12 @@
static jboolean stopExpansion = JNI_FALSE;
static jboolean relaunch = JNI_FALSE;
-JNIEXPORT void
+/*
+ * Prototypes for internal functions.
+ */
+static jboolean expand(JLI_List args, const char *str, const char *var_name);
+
+JNIEXPORT void JNICALL
JLI_InitArgProcessing(jboolean hasJavaArgs, jboolean disableArgFile) {
// No expansion for relaunch
if (argsCount != 1) {
@@ -96,7 +101,7 @@
firstAppArgIndex = hasJavaArgs ? 0: NOT_FOUND;
}
-JNIEXPORT int
+JNIEXPORT int JNICALL
JLI_GetAppArgIndex() {
// Will be 0 for tools
return firstAppArgIndex;
@@ -300,6 +305,8 @@
ctx.state = FIND_NEXT;
ctx.parts = JLI_List_new(4);
+ // initialize to avoid -Werror=maybe-uninitialized issues from gcc 7.3 onwards.
+ ctx.quote_char = '"';
/* arbitrarily pick 8, seems to be a reasonable number of arguments */
rv = JLI_List_new(8);
@@ -376,9 +383,22 @@
return rv;
}
-JNIEXPORT JLI_List
-JLI_PreprocessArg(const char *arg)
-{
+/*
+ * expand a string into a list of words separated by whitespace.
+ */
+static JLI_List expandArg(const char *arg) {
+ JLI_List rv;
+
+ /* arbitrarily pick 8, seems to be a reasonable number of arguments */
+ rv = JLI_List_new(8);
+
+ expand(rv, arg, NULL);
+
+ return rv;
+}
+
+JNIEXPORT JLI_List JNICALL
+JLI_PreprocessArg(const char *arg, jboolean expandSourceOpt) {
JLI_List rv;
if (firstAppArgIndex > 0) {
@@ -392,6 +412,12 @@
return NULL;
}
+ if (expandSourceOpt
+ && JLI_StrCCmp(arg, "--source") == 0
+ && JLI_StrChr(arg, ' ') != NULL) {
+ return expandArg(arg);
+ }
+
if (arg[0] != '@') {
checkArg(arg);
return NULL;
@@ -432,12 +458,9 @@
JLI_StrCmp(arg, "--full-version") == 0;
}
-JNIEXPORT jboolean
+JNIEXPORT jboolean JNICALL
JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
char *env = getenv(var_name);
- char *p, *arg;
- char quote;
- JLI_List argsInFile;
if (firstAppArgIndex == 0) {
// Not 'java', return
@@ -453,44 +476,64 @@
}
JLI_ReportMessage(ARG_INFO_ENVVAR, var_name, env);
+ return expand(args, env, var_name);
+}
+
+/*
+ * Expand a string into a list of args.
+ * If the string is the result of looking up an environment variable,
+ * var_name should be set to the name of that environment variable,
+ * for use if needed in error messages.
+ */
+
+static jboolean expand(JLI_List args, const char *str, const char *var_name) {
+ jboolean inEnvVar = (var_name != NULL);
+
+ char *p, *arg;
+ char quote;
+ JLI_List argsInFile;
// This is retained until the process terminates as it is saved as the args
- p = JLI_MemAlloc(JLI_StrLen(env) + 1);
- while (*env != '\0') {
- while (*env != '\0' && isspace(*env)) {
- env++;
+ p = JLI_MemAlloc(JLI_StrLen(str) + 1);
+ while (*str != '\0') {
+ while (*str != '\0' && isspace(*str)) {
+ str++;
}
// Trailing space
- if (*env == '\0') {
+ if (*str == '\0') {
break;
}
arg = p;
- while (*env != '\0' && !isspace(*env)) {
- if (*env == '"' || *env == '\'') {
- quote = *env++;
- while (*env != quote && *env != '\0') {
- *p++ = *env++;
+ while (*str != '\0' && !isspace(*str)) {
+ if (inEnvVar && (*str == '"' || *str == '\'')) {
+ quote = *str++;
+ while (*str != quote && *str != '\0') {
+ *p++ = *str++;
}
- if (*env == '\0') {
+ if (*str == '\0') {
JLI_ReportMessage(ARG_ERROR8, var_name);
exit(1);
}
- env++;
+ str++;
} else {
- *p++ = *env++;
+ *p++ = *str++;
}
}
*p++ = '\0';
- argsInFile = JLI_PreprocessArg(arg);
+ argsInFile = JLI_PreprocessArg(arg, JNI_FALSE);
if (NULL == argsInFile) {
if (isTerminalOpt(arg)) {
- JLI_ReportMessage(ARG_ERROR9, arg, var_name);
+ if (inEnvVar) {
+ JLI_ReportMessage(ARG_ERROR9, arg, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR15, arg);
+ }
exit(1);
}
JLI_List_add(args, arg);
@@ -501,7 +544,11 @@
for (idx = 0; idx < cnt; idx++) {
arg = argsInFile->elements[idx];
if (isTerminalOpt(arg)) {
- JLI_ReportMessage(ARG_ERROR10, arg, argFile, var_name);
+ if (inEnvVar) {
+ JLI_ReportMessage(ARG_ERROR10, arg, argFile, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR16, arg, argFile);
+ }
exit(1);
}
JLI_List_add(args, arg);
@@ -517,11 +564,15 @@
* caught now.
*/
if (firstAppArgIndex != NOT_FOUND) {
- JLI_ReportMessage(ARG_ERROR11, var_name);
+ if (inEnvVar) {
+ JLI_ReportMessage(ARG_ERROR11, var_name);
+ } else {
+ JLI_ReportMessage(ARG_ERROR17);
+ }
exit(1);
}
- assert (*env == '\0' || isspace(*env));
+ assert (*str == '\0' || isspace(*str));
}
return JNI_TRUE;
@@ -642,7 +693,7 @@
if (argc > 1) {
for (i = 0; i < argc; i++) {
- JLI_List tokens = JLI_PreprocessArg(argv[i]);
+ JLI_List tokens = JLI_PreprocessArg(argv[i], JNI_FALSE);
if (NULL != tokens) {
for (j = 0; j < tokens->size; j++) {
printf("Token[%lu]: <%s>\n", (unsigned long) j, tokens->elements[j]);