1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  @test
  26  @summary <rdar://problem/4486195>
  27  @summary This test ensures that we can call Runtime.exec() with a command
  28  @summary (and arguments) that contains extended characters like é, ü, ç etc
  29  @summary It also tests whether environment variables with extended chars
  30  @summary are passed correctly.
  31  @summary See <rdar://problem/4404074> and <rdar://problem/4408322>
  32  @summary com.apple.junit.java.lang.Runtime;
  33  @run main RuntimeExecExtendedCharsTest
  34  */
  35 
  36 import junit.framework.*;
  37 
  38 import java.io.*;
  39 
  40 public class RuntimeExecExtendedCharsTest extends TestCase
  41 {
  42     private static int fileCount = 0;
  43 
  44     String arg1 = "hélløöüç";
  45     String arg2 = "noaccent";
  46     String env1 = arg1;
  47     String env2 = arg2;
  48 
  49     String writeLine1 = "echo \"ARG1=$1\"";
  50     String writeLine2 = "echo \"ARG2=$2\"";
  51     String writeLine3 = "echo \"ENV1=$ENV1\"";
  52     String writeLine4 = "echo \"ENV2=$ENV2\"";
  53 
  54     String readLine1 = new String("ARG1=" + arg1);
  55     String readLine2 = new String("ARG2=" + arg2);
  56     String readLine3 = new String("ENV1=" + env1);
  57     String readLine4 = new String("ENV2=" + env2);
  58 
  59     public static Test suite() {
  60         return new TestSuite(RuntimeExecExtendedCharsTest.class);
  61     }
  62 
  63     public static void main (String[] args) throws RuntimeException {
  64         TestResult tr = junit.textui.TestRunner.run(suite());
  65         if((tr.errorCount() != 0) || (tr.failureCount() != 0)) {
  66             throw new RuntimeException("### Unexpected JUnit errors or failures.");
  67         }
  68     }
  69 
  70     public void testRuntimeExec() throws Exception {
  71         // "HelloÇüéâäà.txt"
  72         // this should work on local volumes in <= 1.4.2
  73         execFile("Hello\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0.sh");
  74 
  75         // Decomposed "HelloÇüéâäà.txt"
  76         // this should work on local volumes AND remote AFP volumes in <= 1.4.2
  77         execFile("HelloC\u0327u\u0308e\u0301a\u0302a\u0308a\u0300.sh");
  78     }
  79 
  80     private File createFile(String aName) throws Exception {
  81         String fullFileName = new String(System.getProperty("java.io.tmpdir") + "/" + aName + fileCount);
  82         fileCount++;
  83         File aFile = new File(fullFileName);
  84         aFile.deleteOnExit();
  85 
  86         // Warn folks that previous test did not clean up properly, probably because of a harness crash
  87         if (aFile.exists()) {
  88             System.err.println("WARNING: deleting file "+ aFile.getCanonicalPath() +" , as a copy was left from earlier test.");
  89             aFile.delete();
  90         }
  91 
  92         FileOutputStream aFileOutputStream = null;
  93         aFileOutputStream = new FileOutputStream(aFile);
  94         PrintWriter aPrintWriter = new PrintWriter(new OutputStreamWriter(aFileOutputStream), true);
  95         aPrintWriter.println(writeLine1);
  96         aPrintWriter.println(writeLine2);
  97         aPrintWriter.println(writeLine3);
  98         aPrintWriter.println(writeLine4);
  99 
 100         aFileOutputStream.close();
 101 
 102         String execArgs[] = new String[] {"chmod", "a+x", aFile.getAbsolutePath()};
 103         Process aProcess = Runtime.getRuntime().exec(execArgs);
 104         aProcess.waitFor();
 105         assertEquals("Could not chmod file", aProcess.exitValue(), 0);
 106 
 107         return aFile;
 108     }
 109 
 110     private void execFile(String name) throws Exception {
 111         execFile(name, false);
 112     }
 113 
 114     private void execFile(String name, boolean testArgs) throws Exception {
 115         execFile(name, testArgs, false);
 116     }
 117 
 118     private void execFile(String name, boolean testArgs, boolean testEnv) throws Exception {
 119         execFile(name, testArgs, testEnv, false);
 120     }
 121 
 122     private void execFile(String aName, boolean testArgs, boolean testEnv, @SuppressWarnings("unused") boolean testDir) throws Exception  {
 123         File aFile = createFile(aName);
 124         String execArgs[] = null;
 125         if (testArgs) {
 126             execArgs = new String[] {aFile.getAbsolutePath(), arg1, arg2};
 127         } else {
 128             execArgs = new String[] {aFile.getAbsolutePath()};
 129         }
 130 
 131         {
 132             Process aProcess = null;
 133             try {
 134                 aProcess = Runtime.getRuntime().exec(execArgs);
 135                 aProcess.waitFor();
 136 
 137                 assertEquals("Runtime.exec failed on a filename with accented chars", aProcess.exitValue(), 0);
 138 
 139 
 140                 InputStream anInputStream = aProcess.getInputStream();
 141                 BufferedReader reader = new BufferedReader(new InputStreamReader(anInputStream));
 142                 if (testArgs || testEnv) {
 143                     assertEquals("Did not read the line (1) I expected to read", readLine1, reader.readLine());
 144                     assertEquals("Did not read the line (2) I expected to read", readLine2, reader.readLine());
 145                 }
 146                 if (testEnv) {
 147                     assertEquals("Did not read the line (3) I expected to read", readLine3, reader.readLine());
 148                     assertEquals("Did not read the line (4) I expected to read", readLine4, reader.readLine());
 149                 }
 150             }
 151             catch (Exception e)
 152             {
 153                 e.printStackTrace();
 154             }
 155         }
 156     }
 157 }