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