Skip to content

Commit

Permalink
std.process: add missing check for failed malloc()
Browse files Browse the repository at this point in the history
  • Loading branch information
kubo39 committed Aug 13, 2019
1 parent 5f399cf commit 9719e11
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions std/process.d
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ version (Windows)
import std.windows.syserror;
}

import core.exception : OutOfMemoryError;

import std.internal.cstring;
import std.range.primitives;
import std.stdio;
Expand Down Expand Up @@ -342,6 +344,7 @@ version (Posix) private enum InternalError : ubyte
chdir,
getrlimit,
doubleFork,
malloc,
}

/*
Expand Down Expand Up @@ -510,9 +513,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;
Expand All @@ -530,6 +533,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;
Expand Down Expand Up @@ -646,6 +653,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);
}
Expand Down Expand Up @@ -3914,6 +3924,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));
if (!argv) throw new OutOfMemoryError("Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);

toAStringz(argv, argv_);
Expand All @@ -3924,8 +3935,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));
if (!argv) throw new OutOfMemoryError("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));
if (!envp) throw new OutOfMemoryError("Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_);

toAStringz(argv, argv_);
Expand All @@ -3937,6 +3950,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));
if (!argv_) throw new OutOfMemoryError("Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(argv_);

toAStringz(argv, argv_);
Expand Down Expand Up @@ -3984,8 +3998,10 @@ version (Posix)
else version (Windows)
{
auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
if (!argv) throw new OutOfMemoryError("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));
if (!envp) throw new OutOfMemoryError("Out of memory in std.process.");
scope(exit) core.stdc.stdlib.free(envp_);

toAStringz(argv, argv_);
Expand Down

0 comments on commit 9719e11

Please sign in to comment.