1 /**
   2  * @test
   3  * @bug 8012453 
   4  * @run main/othervm ExecCommand
   5  * @summary workaround for legacy applications with Runtime.getRuntime().exec(String command)
   6  */
   7 
   8 import java.io.BufferedWriter;
   9 import java.io.File;
  10 import java.io.FileWriter;
  11 import java.io.IOException;
  12 import java.security.AccessControlException;
  13 
  14 public class ExecCommand {
  15     static class SecurityMan extends SecurityManager {
  16         public static String unquote(String str)
  17         {
  18             int length = (str == null) 
  19                 ? 0 
  20                 : str.length();
  21 
  22             if (length > 1 
  23                 && str.charAt(0) == '\"' 
  24                 && str.charAt(length - 1) == '\"')
  25             {
  26                return str.substring(1, length - 1); 
  27             }
  28             return str;
  29         }        
  30         
  31         @Override public void checkExec(String cmd) {
  32             String ncmd = (new File(unquote(cmd))).getPath();
  33             if ( ncmd.equals(".\\Program")  
  34               || ncmd.equals(".\\Program File\\do.cmd")
  35               || ncmd.equals(".\\Program.cmd"))
  36             {
  37                 return;
  38             }
  39             super.checkExec(cmd);            
  40         }
  41     }
  42 
  43     // Parameters for the Runtime.exec calls
  44     private static final String TEST_RTE_ARG[] = {
  45         ".\\Program Files\\do.cmd",
  46         "\".\\Program Files\\do.cmd\" arg",
  47         // compatibility
  48         "\".\\Program.cmd\" arg",
  49         ".\\Program.cmd arg",        
  50     };
  51     
  52     private static final String doCmdCopy[] = {
  53         ".\\Program.cmd",        
  54         ".\\Program Files\\do.cmd",
  55     };
  56     
  57     // Golden image for results
  58     private static final String TEST_RTE_GI[][] = {
  59                     //Pure system | Legacy mode | Legacy mode & SM
  60         // last IOException due to SM - no legacy mode [".\Program] - OK        
  61         new String[]{"IOException", "Success",  "IOException"},            //[.\Program File\do.cmd]        
  62         // AccessControlException due to wrong file name [".\Program] - OK
  63         new String[]{"Success",     "Success",  "AccessControlException"}, //[".\Program File\do.cmd" arg]
  64         // compatibility
  65         new String[]{"Success",     "Success",  "Success"},                //[".\Program.cmd"]
  66         new String[]{"Success",     "Success",  "Success"}                 //[.\Program.cmd]    
  67     };    
  68     
  69     public static void main(String[] _args) throws Exception { 
  70         if (!System.getProperty("os.name").startsWith("Windows")) {
  71             return;
  72         }   
  73         
  74         // tear up    
  75         try {
  76             new File(".\\Program Files").mkdirs();
  77             
  78             for (int i = 0; i < doCmdCopy.length; ++i) {            
  79                 BufferedWriter outCmd = new BufferedWriter(
  80                         new FileWriter(doCmdCopy[i]));
  81                 outCmd.write("@echo %1");
  82                 outCmd.close();
  83             } 
  84         } catch (IOException e) {
  85             throw new Error(e.getMessage());
  86         }        
  87         
  88         // action
  89         for (int k = 0; k < 3; ++k) {
  90             switch (k) {
  91             case 1:    
  92                 System.setProperty("jdk.lang.Process.allowAmbigousCommands", "");
  93                 break;
  94             case 2:    
  95                 System.setSecurityManager( new SecurityMan() );
  96                 break;
  97             }
  98             for (int i = 0; i < TEST_RTE_ARG.length; ++i) {
  99                 String outRes;            
 100                 try {
 101                     Process exec = Runtime.getRuntime().exec(TEST_RTE_ARG[i]);
 102                     exec.waitFor();
 103                     outRes = "Success";
 104                 } catch (IOException ioe) {
 105                     outRes = "IOException: " + ioe.getMessage();
 106                 } catch (IllegalArgumentException iae) {
 107                     outRes = "IllegalArgumentException: " + iae.getMessage();
 108                 } catch (AccessControlException se) {
 109                     outRes = "AccessControlException: " + se.getMessage();
 110                 }
 111 
 112                 if (!outRes.startsWith(TEST_RTE_GI[i][k])) {
 113                     throw new Error("Unexpected output! Step" + k + "" + i
 114                                 + " \nArgument: " + TEST_RTE_ARG[i]
 115                                 + "\nExpected: " + TEST_RTE_GI[i][k]
 116                                 + "\n  Output: " + outRes);
 117                 } else {
 118                     System.out.println("RTE OK:" + TEST_RTE_ARG[i]);
 119                 }
 120             }        
 121         }    
 122     }           
 123 }