...
A process that tries to read input on an empty input stream will block until input is supplied. Consequently, input must be supplied when invoking such a process that expects input.
Output from an external process can exhaust the available buffer for the output or error stream. When this occurs, it can block the external process as well, preventing any forward progress for both the Java program and the external processes. Note that many platforms limit the buffer size available for the output streams. Consequently, when invoking an external process, if the process sends any data to its output stream, the process's output stream must be emptied. And if the process sends any data to its error stream, the error stream must also be emptied.
Noncompliant Code Example (exitValue()
)
This noncompliant code example invokes We will assume that the following code samples use the external command notemaker
, a hypothetical cross-platform notepad application . We will also assume that notemaker
using the external command notemaker
. The notemaker
application does not read its input stream, but does send sends output to both its output stream and error stream.
...
This noncompliant code example invokes notemaker
using the exec()
method, which returns an object of a subclass of the abstract
class java.lang.Process
. The exitValue()
method returns the exit value for processes that have terminated, but it throws an IllegalThreadStateException
when invoked on an active process. Because this noncompliant example program fails to wait for the notemaker
process to terminate, the call to exitValue()
is likely to throw an {IllegalThreadStateException}}.
...
In this noncompliant code example, the waitFor()
method blocks the calling thread until the the invoked notemaker
process terminates. This prevents the IllegalThreadStateException
seen in from the previous example. However, the example program may experience an arbitrary delay before termination. Output from the notemaker
process can exhaust the available buffer for the output or error stream since because neither stream is read while waiting for the process to complete. If either buffer becomes full, it can block the notemaker
process as well, preventing all forward progress for both the notemake notemaker
process and the Java program.
Code Block | ||
---|---|---|
| ||
public class Exec { public static void main(String args[]) throws IOException { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("notemaker"); int exitVal = proc.waitFor(); } } |
Noncompliant Code Example (
...
Input Stream)
This noncompliant code example properly drains the input stream from the process, thereby preventing the input stream buffer from becoming full and blocking. However, it ignores the error stream, which can also fill and cause the process to block.
Code Block | ||
---|---|---|
| ||
public class Exec { public static void main(String args[]) throws IOException, InterruptedException { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("notemaker"); InputStream is = proc.getInputStream(); int c; while ((c = is.read()) != -1) { System.out.print((char) c); } int exitVal = proc.waitFor(); } } |
...
This compliant solution redirects the process's error stream to its input stream. ThusConsequently, the program can drain the single output stream without fear of blockage.
Code Block | ||
---|---|---|
| ||
public class Exec { public static void main(String args[]) throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder("notemaker"); pb = pb.redirectErrorStream(true); Process proc = pb.start(); InputStream is = proc.getInputStream(); int c; while ((c = is.read()) != -1) { System.out.print((char) c); } int exitVal = proc.waitFor(); } } |
Compliant Solution (
...
Input Stream and Error Stream)
This compliant solution spawns two threads to consume the input stream and error stream. Consequently, the process does not block.
...
FIO10-EX0: A process that does not read input from its input stream need not have data supplied there. Likewise Similarly, a process that does not send output to its output stream need not have its output stream emptied. And a proces that does not send output to its error stream need not have its error stream emptiedor error streams does not need to empty these streams.
Risk Assessment
Misuse of the exec()
method can result in runtime exceptions and in denial of service vulnerabilities.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0a87b9be3ee3769f-f4a14613-4e434369-b15aa452-6c1856835b782c349da973a5"><ac:plain-text-body><![CDATA[ | [[API 06 | AA. Bibliography#API 06]] | method [exec() | http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String)] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="6d5145eeeef43333-7fd59492-4d4642a4-b30f9341-ceaee4ee41ae85124e660a3f"><ac:plain-text-body><![CDATA[ | [[Daconta 00 | AA. Bibliography#Daconta 00]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="f2917121c01e60ca-b3a97202-4bfd473e-9dfcac60-4936e0e3ed8c81bef4871d83"><ac:plain-text-body><![CDATA[ | [[Daconta 03 | AA. Bibliography#Daconta 03]] | Pitfall 1 | ]]></ac:plain-text-body></ac:structured-macro> |
...