std.process: add missing check for failed malloc() (#7116)

std.process: add missing check for failed malloc()
merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
This commit is contained in:
Hiroki Noda 2019-08-20 19:34:52 +09:00 committed by The Dlang Bot
parent ad70ff2e08
commit c25c94bb47

View file

@ -98,6 +98,9 @@ version (Windows)
import std.windows.syserror; import std.windows.syserror;
} }
import core.exception : OutOfMemoryError;
import std.exception : enforce;
import std.internal.cstring; import std.internal.cstring;
import std.range.primitives; import std.range.primitives;
import std.stdio; import std.stdio;
@ -342,6 +345,7 @@ version (Posix) private enum InternalError : ubyte
chdir, chdir,
getrlimit, getrlimit,
doubleFork, doubleFork,
malloc,
} }
/* /*
@ -510,9 +514,9 @@ private Pid spawnProcessImpl(scope const(char[])[] args,
if (!(config & Config.inheritFDs)) if (!(config & Config.inheritFDs))
{ {
// NOTE: malloc() and getrlimit() are not on the POSIX async // NOTE: malloc() and getrlimit() are not on the POSIX async
// signal safe functions list, but practically this should not // signal safe functions list, but practically this should
// be a problem. Tha Java VM and CPython also use malloc() in // not be a problem. Java VM and CPython also use malloc()
// its own implementation. // in its own implementation via opendir().
import core.stdc.stdlib : malloc; import core.stdc.stdlib : malloc;
import core.sys.posix.poll : pollfd, poll, POLLNVAL; import core.sys.posix.poll : pollfd, poll, POLLNVAL;
import core.sys.posix.sys.resource : rlimit, getrlimit, RLIMIT_NOFILE; import core.sys.posix.sys.resource : rlimit, getrlimit, RLIMIT_NOFILE;
@ -530,6 +534,10 @@ private Pid spawnProcessImpl(scope const(char[])[] args,
// Call poll() to see which ones are actually open: // Call poll() to see which ones are actually open:
auto pfds = cast(pollfd*) malloc(pollfd.sizeof * maxToClose); auto pfds = cast(pollfd*) malloc(pollfd.sizeof * maxToClose);
if (pfds is null)
{
abortOnError(forkPipeOut, InternalError.malloc, .errno);
}
foreach (i; 0 .. maxToClose) foreach (i; 0 .. maxToClose)
{ {
pfds[i].fd = i + 3; pfds[i].fd = i + 3;
@ -646,6 +654,9 @@ private Pid spawnProcessImpl(scope const(char[])[] args,
assert(config & Config.detached); assert(config & Config.detached);
errorMsg = "Failed to fork twice"; errorMsg = "Failed to fork twice";
break; break;
case InternalError.malloc:
errorMsg = "Failed to allocate memory";
break;
case InternalError.noerror: case InternalError.noerror:
assert(false); assert(false);
} }
@ -1516,7 +1527,6 @@ private:
version (Posix) version (Posix)
int performWait(bool block) @trusted int performWait(bool block) @trusted
{ {
import std.exception : enforce;
enforce!ProcessException(owned, "Can't wait on a detached process"); enforce!ProcessException(owned, "Can't wait on a detached process");
if (_processID == terminated) return _exitCode; if (_processID == terminated) return _exitCode;
int exitCode; int exitCode;
@ -1566,7 +1576,6 @@ private:
{ {
int performWait(bool block) @trusted int performWait(bool block) @trusted
{ {
import std.exception : enforce;
enforce!ProcessException(owned, "Can't wait on a detached process"); enforce!ProcessException(owned, "Can't wait on a detached process");
if (_processID == terminated) return _exitCode; if (_processID == terminated) return _exitCode;
assert(_handle != INVALID_HANDLE_VALUE); assert(_handle != INVALID_HANDLE_VALUE);
@ -1812,7 +1821,6 @@ void kill(Pid pid)
/// ditto /// ditto
void kill(Pid pid, int codeOrSignal) void kill(Pid pid, int codeOrSignal)
{ {
import std.exception : enforce;
enforce!ProcessException(pid.owned, "Can't kill detached process"); enforce!ProcessException(pid.owned, "Can't kill detached process");
version (Windows) version (Windows)
{ {
@ -3342,7 +3350,6 @@ static:
*/ */
string opIndex(scope const(char)[] name) @safe string opIndex(scope const(char)[] name) @safe
{ {
import std.exception : enforce;
string value; string value;
enforce(getImpl(name, value), "Environment variable not found: "~name); enforce(getImpl(name, value), "Environment variable not found: "~name);
return value; return value;
@ -3411,7 +3418,7 @@ static:
{ {
version (Posix) version (Posix)
{ {
import std.exception : enforce, errnoEnforce; import std.exception : errnoEnforce;
if (value is null) if (value is null)
{ {
remove(name); remove(name);
@ -3431,7 +3438,6 @@ static:
} }
else version (Windows) else version (Windows)
{ {
import std.exception : enforce;
enforce( enforce(
SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()), SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()),
sysErrorString(GetLastError()) sysErrorString(GetLastError())
@ -3541,7 +3547,6 @@ static:
} }
else version (Windows) else version (Windows)
{ {
import std.exception : enforce;
import std.uni : toUpper; import std.uni : toUpper;
auto envBlock = GetEnvironmentStringsW(); auto envBlock = GetEnvironmentStringsW();
enforce(envBlock, "Failed to retrieve environment variables."); enforce(envBlock, "Failed to retrieve environment variables.");
@ -3914,6 +3919,7 @@ extern(C)
private int execv_(in string pathname, in string[] argv) private int execv_(in string pathname, in string[] argv)
{ {
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length)); auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_); scope(exit) core.stdc.stdlib.free(argv_);
toAStringz(argv, argv_); toAStringz(argv, argv_);
@ -3924,8 +3930,10 @@ private int execv_(in string pathname, in string[] argv)
private int execve_(in string pathname, in string[] argv, in string[] envp) private int execve_(in string pathname, in string[] argv, in string[] envp)
{ {
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length)); auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_); scope(exit) core.stdc.stdlib.free(argv_);
auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length)); auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_); scope(exit) core.stdc.stdlib.free(envp_);
toAStringz(argv, argv_); toAStringz(argv, argv_);
@ -3937,6 +3945,7 @@ private int execve_(in string pathname, in string[] argv, in string[] envp)
private int execvp_(in string pathname, in string[] argv) private int execvp_(in string pathname, in string[] argv)
{ {
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length)); auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_); scope(exit) core.stdc.stdlib.free(argv_);
toAStringz(argv, argv_); toAStringz(argv, argv_);
@ -3984,8 +3993,10 @@ version (Posix)
else version (Windows) else version (Windows)
{ {
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length)); auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_); scope(exit) core.stdc.stdlib.free(argv_);
auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length)); auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_); scope(exit) core.stdc.stdlib.free(envp_);
toAStringz(argv, argv_); toAStringz(argv, argv_);