8067796: (process) Process.waitFor(timeout, unit) doesn't throw NPE if timeout is less than, or equal to zero when unit == null
Summary: Implement checking for NPE in Process implementation before other conditions
Reviewed-by: martin, chegar
--- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Mon Mar 23 09:45:32 2015 -0700
+++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Mon Mar 23 10:13:32 2015 -0400
@@ -496,12 +496,11 @@
public synchronized boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
+ long remainingNanos = unit.toNanos(timeout); // throw NPE before other conditions
if (hasExited) return true;
if (timeout <= 0) return false;
- long remainingNanos = unit.toNanos(timeout);
long deadline = System.nanoTime() + remainingNanos;
-
do {
// Round up to next millisecond
wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
--- a/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Mon Mar 23 09:45:32 2015 -0700
+++ b/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Mon Mar 23 10:13:32 2015 -0400
@@ -458,12 +458,11 @@
public boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
+ long remainingNanos = unit.toNanos(timeout); // throw NPE before other conditions
if (getExitCodeProcess(handle) != STILL_ACTIVE) return true;
if (timeout <= 0) return false;
- long remainingNanos = unit.toNanos(timeout);
long deadline = System.nanoTime() + remainingNanos ;
-
do {
// Round up to next millisecond
long msTimeout = TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L);
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Mon Mar 23 09:45:32 2015 -0700
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Mon Mar 23 10:13:32 2015 -0400
@@ -27,6 +27,7 @@
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* 4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464
+ * 8067796
* @summary Basic tests for Process and Environment Variable code
* @run main/othervm/timeout=300 Basic
* @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=fork Basic
@@ -2387,6 +2388,56 @@
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
+ // Check that Process.waitFor(timeout, null) throws NPE.
+ //----------------------------------------------------------------
+ try {
+ List<String> childArgs = new ArrayList<String>(javaChildArgs);
+ childArgs.add("sleep");
+ final Process p = new ProcessBuilder(childArgs).start();
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(10L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(0L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(-1L, null));
+ // Terminate process and recheck after it exits
+ p.destroy();
+ p.waitFor();
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(10L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(0L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(-1L, null));
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
+ // Check that default implementation of Process.waitFor(timeout, null) throws NPE.
+ //----------------------------------------------------------------
+ try {
+ List<String> childArgs = new ArrayList<String>(javaChildArgs);
+ childArgs.add("sleep");
+ final Process proc = new ProcessBuilder(childArgs).start();
+ final DelegatingProcess p = new DelegatingProcess(proc);
+
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(10L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(0L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(-1L, null));
+ // Terminate process and recheck after it exits
+ p.destroy();
+ p.waitFor();
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(10L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(0L, null));
+ THROWS(NullPointerException.class,
+ () -> p.waitFor(-1L, null));
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
// Check the default implementation for
// Process.waitFor(long, TimeUnit)
//----------------------------------------------------------------