FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When you pass a command parameter off to ProcessBuild that references a file name with a space and ends with a wildcard (ie \"C:\\Documents and Settings\\\Java"*), ProcessImpl attempts to verify that the parameter is correctly quoted. Unfortunately the logic that does so assumes that the if the value in the parameter starts with a quote, that the last character must end with a quote. This logic is not valid, because it does not allow a parameter like the one above. Also it will not accurately catch a parameter that has an odd number of quotes like this \"Hello \" Goodbye\", which starts and ends with a quote, but also has a quote in the middle.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
I do not have a current work around, as I can not make changes to the ProcessImpl code, or create a working copy in my environment. I was able to create a version that functioned enough to allow me to test a possible fix, which is included below.
In the method ProcessImpl I replaced this section:
167 if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
168 if (s.charAt(0) != '"') {
169 cmdbuf.append('"');
170 cmdbuf.append(s);
171 if (s.endsWith("\\")) {
172 cmdbuf.append("\\");
173 }
174 cmdbuf.append('"');
175 } else if (s.endsWith("\"")) {
176 /* The argument has already been quoted. */
177 cmdbuf.append(s);
178 } else {
179 /* Unmatched quote for the argument. */
180 throw new IllegalArgumentException();
181 }
182 } else {
183 cmdbuf.append(s);
184 }
185 }
With this code
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
if (s.charAt(0) != '"') {
cmdbuf.append('"');
cmdbuf.append(s);
if (s.endsWith("\\")) {
cmdbuf.append("\\");
}
cmdbuf.append('"');
} else {
Boolean quotesMatch = true;
for (int pos = 0; pos < s.length(); pos++) {
//System.out.println(s.substring(pos,1));
if (s.charAt(pos) == '"') {
quotesMatch = !quotesMatch;
}
}
/* do we have an equal number of quotes */
if (quotesMatch) {
cmdbuf.append(s);
} else {
/* Unmatched quote for the argument. */
throw new IllegalArgumentException();
}
}
} else {
cmdbuf.append(s);
}
Looking a the values in the cmdbuf, it seems to have resolved the problem.
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When you pass a command parameter off to ProcessBuild that references a file name with a space and ends with a wildcard (ie \"C:\\Documents and Settings\\\Java"*), ProcessImpl attempts to verify that the parameter is correctly quoted. Unfortunately the logic that does so assumes that the if the value in the parameter starts with a quote, that the last character must end with a quote. This logic is not valid, because it does not allow a parameter like the one above. Also it will not accurately catch a parameter that has an odd number of quotes like this \"Hello \" Goodbye\", which starts and ends with a quote, but also has a quote in the middle.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
I do not have a current work around, as I can not make changes to the ProcessImpl code, or create a working copy in my environment. I was able to create a version that functioned enough to allow me to test a possible fix, which is included below.
In the method ProcessImpl I replaced this section:
167 if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
168 if (s.charAt(0) != '"') {
169 cmdbuf.append('"');
170 cmdbuf.append(s);
171 if (s.endsWith("\\")) {
172 cmdbuf.append("\\");
173 }
174 cmdbuf.append('"');
175 } else if (s.endsWith("\"")) {
176 /* The argument has already been quoted. */
177 cmdbuf.append(s);
178 } else {
179 /* Unmatched quote for the argument. */
180 throw new IllegalArgumentException();
181 }
182 } else {
183 cmdbuf.append(s);
184 }
185 }
With this code
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
if (s.charAt(0) != '"') {
cmdbuf.append('"');
cmdbuf.append(s);
if (s.endsWith("\\")) {
cmdbuf.append("\\");
}
cmdbuf.append('"');
} else {
Boolean quotesMatch = true;
for (int pos = 0; pos < s.length(); pos++) {
//System.out.println(s.substring(pos,1));
if (s.charAt(pos) == '"') {
quotesMatch = !quotesMatch;
}
}
/* do we have an equal number of quotes */
if (quotesMatch) {
cmdbuf.append(s);
} else {
/* Unmatched quote for the argument. */
throw new IllegalArgumentException();
}
}
} else {
cmdbuf.append(s);
}
Looking a the values in the cmdbuf, it seems to have resolved the problem.
- duplicates
-
JDK-7051946 Runtime.exec(String command) / ProcessBuilder command parsing issues
- Resolved
- relates to
-
JDK-8190409 ProcessBuilder does not handle the spaces in the arguments
- Closed