std.process: Fix memory corruption in exec functions

Fixes issue #10639.
This commit is contained in:
Vladimir Panteleev 2025-02-17 20:48:27 +00:00 committed by The Dlang Bot
parent ea28abfadb
commit bb0c2953dd

View file

@ -4315,14 +4315,14 @@ version (Posix)
import core.sys.posix.stdlib;
}
private void toAStringz(in string[] a, const(char)**az)
private const(char)** toAStringz(in string[] a)
{
import std.string : toStringz;
foreach (string s; a)
{
*az++ = toStringz(s);
}
*az = null;
auto p = (new const(char)*[1 + a.length]).ptr;
foreach (i, string s; a)
p[i] = toStringz(s);
p[a.length] = null;
return p;
}
@ -4452,45 +4452,17 @@ extern(C)
private int execv_(in string pathname, in string[] argv)
{
import core.exception : OutOfMemoryError;
import std.exception : enforce;
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_);
return execv(pathname.tempCString(), argv_);
return execv(pathname.tempCString(), toAStringz(argv));
}
private int execve_(in string pathname, in string[] argv, in string[] envp)
{
import core.exception : OutOfMemoryError;
import std.exception : enforce;
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_);
toAStringz(envp, envp_);
return execve(pathname.tempCString(), argv_, envp_);
return execve(pathname.tempCString(), toAStringz(argv), toAStringz(envp));
}
private int execvp_(in string pathname, in string[] argv)
{
import core.exception : OutOfMemoryError;
import std.exception : enforce;
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_);
return execvp(pathname.tempCString(), argv_);
return execvp(pathname.tempCString(), toAStringz(argv));
}
private int execvpe_(in string pathname, in string[] argv, in string[] envp)
@ -4532,19 +4504,7 @@ version (Posix)
}
else version (Windows)
{
import core.exception : OutOfMemoryError;
import std.exception : enforce;
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_);
toAStringz(envp, envp_);
return execvpe(pathname.tempCString(), argv_, envp_);
return execvpe(pathname.tempCString(), toAStringz(argv), toAStringz(envp));
}
else
{