Skip to content

Commit 7ab0e8c

Browse files
authored
Merge pull request #6274 from JackStouffer/issue18178
Fix Issue 18178 - std.path should be usable in @safe merged-on-behalf-of: Jack Stouffer <[email protected]>
2 parents 78c67dc + f6e4416 commit 7ab0e8c

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

std/path.d

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3937,7 +3937,7 @@ if (isConvertibleToString!Range)
39373937
}
39383938
-----
39393939
*/
3940-
string expandTilde(string inputPath) nothrow
3940+
string expandTilde(string inputPath) @safe nothrow
39413941
{
39423942
version(Posix)
39433943
{
@@ -3951,9 +3951,10 @@ string expandTilde(string inputPath) nothrow
39513951
is joined to path[char_pos .. length] if char_pos is smaller
39523952
than length, otherwise path is not appended to c_path.
39533953
*/
3954-
static string combineCPathWithDPath(char* c_path, string path, size_t char_pos) nothrow
3954+
static string combineCPathWithDPath(char* c_path, string path, size_t char_pos) @trusted nothrow
39553955
{
39563956
import core.stdc.string : strlen;
3957+
import std.exception : assumeUnique;
39573958

39583959
assert(c_path != null);
39593960
assert(path.length > 0);
@@ -3966,11 +3967,10 @@ string expandTilde(string inputPath) nothrow
39663967
if (end && isDirSeparator(c_path[end - 1]))
39673968
end--;
39683969

3969-
// (this is the only GC allocation done in expandTilde())
39703970
string cp;
39713971
if (char_pos < path.length)
39723972
// Append something from path
3973-
cp = cast(string)(c_path[0 .. end] ~ path[char_pos .. $]);
3973+
cp = assumeUnique(c_path[0 .. end] ~ path[char_pos .. $]);
39743974
else
39753975
// Create our own copy, as lifetime of c_path is undocumented
39763976
cp = c_path[0 .. end].idup;
@@ -3979,23 +3979,23 @@ string expandTilde(string inputPath) nothrow
39793979
}
39803980

39813981
// Replaces the tilde from path with the environment variable HOME.
3982-
static string expandFromEnvironment(string path) nothrow
3982+
static string expandFromEnvironment(string path) @safe nothrow
39833983
{
39843984
import core.stdc.stdlib : getenv;
39853985

39863986
assert(path.length >= 1);
39873987
assert(path[0] == '~');
39883988

39893989
// Get HOME and use that to replace the tilde.
3990-
auto home = getenv("HOME");
3990+
auto home = () @trusted { return getenv("HOME"); } ();
39913991
if (home == null)
39923992
return path;
39933993

39943994
return combineCPathWithDPath(home, path, 1);
39953995
}
39963996

39973997
// Replaces the tilde from path with the path from the user database.
3998-
static string expandFromDatabase(string path) nothrow
3998+
static string expandFromDatabase(string path) @safe nothrow
39993999
{
40004000
// bionic doesn't really support this, as getpwnam_r
40014001
// isn't provided and getpwnam is basically just a stub
@@ -4015,10 +4015,7 @@ string expandTilde(string inputPath) nothrow
40154015
auto last_char = indexOf(path, dirSeparator[0]);
40164016

40174017
size_t username_len = (last_char == -1) ? path.length : last_char;
4018-
char* username = cast(char*) malloc(username_len * char.sizeof);
4019-
if (!username)
4020-
onOutOfMemoryError();
4021-
scope(exit) free(username);
4018+
char[] username = new char[username_len * char.sizeof];
40224019

40234020
if (last_char == -1)
40244021
{
@@ -4038,24 +4035,27 @@ string expandTilde(string inputPath) nothrow
40384035
uint extra_memory_size = 2;
40394036
else
40404037
uint extra_memory_size = 5 * 1024;
4041-
char* extra_memory;
4042-
scope(exit) free(extra_memory);
4038+
char[] extra_memory;
40434039

40444040
passwd result;
40454041
while (1)
40464042
{
4047-
extra_memory = cast(char*) realloc(extra_memory, extra_memory_size * char.sizeof);
4048-
if (extra_memory == null)
4049-
onOutOfMemoryError();
4043+
extra_memory.length += extra_memory_size;
40504044

40514045
// Obtain info from database.
40524046
passwd *verify;
40534047
errno = 0;
4054-
if (getpwnam_r(username, &result, extra_memory, extra_memory_size,
4055-
&verify) == 0)
4048+
auto passResult = () @trusted { return getpwnam_r(
4049+
&username[0],
4050+
&result,
4051+
&extra_memory[0],
4052+
extra_memory.length,
4053+
&verify
4054+
); } ();
4055+
if (passResult == 0)
40564056
{
40574057
// Succeeded if verify points at result
4058-
if (verify == &result)
4058+
if (verify == () @trusted { return &result; } ())
40594059
// username is found
40604060
path = combineCPathWithDPath(result.pw_dir, path, last_char);
40614061
break;

0 commit comments

Comments
 (0)