JDK-7177083 : ProcessBuilder does not handle command parameters with spaces correctly
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2012-06-14
  • Updated: 2018-02-22
  • Resolved: 2012-06-22
Related Reports
Duplicate :  
Relates :  
Description
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.

Comments
EVALUATION This appears to be a dup of 7051946, see: http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-September/007674.html
20-06-2012