Merge pull request #5410 from jmdavis/path

Fix safety issues with driveName, stripDrive, and rootName
This commit is contained in:
Sebastian Wilzbach 2018-01-28 02:12:46 +01:00 committed by GitHub
commit 70d3b892ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -688,9 +688,21 @@ if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementT
A slice of $(D path). A slice of $(D path).
*/ */
auto rootName(R)(R path) auto rootName(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
isNarrowString!R) && {
!isConvertibleToString!R) return _rootName(path);
}
/// ditto
auto rootName(C)(C[] path)
if (isSomeChar!C)
{
return _rootName(path);
}
private auto _rootName(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) ||
isNarrowString!R)
{ {
if (path.empty) if (path.empty)
goto Lnull; goto Lnull;
@ -742,6 +754,12 @@ Lnull:
@safe unittest @safe unittest
{ {
assert(testAliasedString!rootName("/foo/bar")); assert(testAliasedString!rootName("/foo/bar"));
enum S : string { a = "/foo/bar" }
assert(S.a.rootName == "/");
char[S.a.length] sa = S.a[];
assert(sa.rootName == "/");
} }
@safe unittest @safe unittest
@ -763,12 +781,6 @@ Lnull:
} }
} }
auto rootName(R)(R path)
if (isConvertibleToString!R)
{
return rootName!(StringTypeOf!R)(path);
}
/** /**
Get the drive portion of a path. Get the drive portion of a path.
@ -784,9 +796,21 @@ if (isConvertibleToString!R)
Always returns an empty range on POSIX. Always returns an empty range on POSIX.
*/ */
auto driveName(R)(R path) auto driveName(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)
isNarrowString!R) && {
!isConvertibleToString!R) return _driveName(path);
}
/// ditto
auto driveName(C)(C[] path)
if (isSomeChar!C)
{
return _driveName(path);
}
private auto _driveName(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) ||
isNarrowString!R)
{ {
version (Windows) version (Windows)
{ {
@ -820,15 +844,20 @@ if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(Element
} }
} }
auto driveName(R)(auto ref R path)
if (isConvertibleToString!R)
{
return driveName!(StringTypeOf!R)(path);
}
@safe unittest @safe unittest
{ {
assert(testAliasedString!driveName(`d:\file`)); assert(testAliasedString!driveName("d:/file"));
version(Posix)
immutable result = "";
else version(Windows)
immutable result = "d:";
enum S : string { a = "d:/file" }
assert(S.a.driveName == result);
char[S.a.length] sa = S.a[];
assert(sa.driveName == result);
} }
@safe unittest @safe unittest
@ -861,9 +890,20 @@ if (isConvertibleToString!R)
Returns: A slice of path without the drive component. Returns: A slice of path without the drive component.
*/ */
auto stripDrive(R)(R path) auto stripDrive(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R)
isNarrowString!R) && {
!isConvertibleToString!R) return _stripDrive(path);
}
/// ditto
auto stripDrive(C)(C[] path)
{
return _stripDrive(path);
}
private auto _stripDrive(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) ||
isNarrowString!R)
{ {
version(Windows) version(Windows)
{ {
@ -883,15 +923,20 @@ if ((isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) ||
} }
} }
auto stripDrive(R)(auto ref R path)
if (isConvertibleToString!R)
{
return stripDrive!(StringTypeOf!R)(path);
}
@safe unittest @safe unittest
{ {
assert(testAliasedString!stripDrive(`d:\dir\file`)); assert(testAliasedString!stripDrive("d:/dir/file"));
version(Posix)
immutable result = "d:/dir/file";
else version(Windows)
immutable result = "/dir/file";
enum S : string { a = "d:/dir/file" }
assert(S.a.stripDrive == result);
char[S.a.length] sa = S.a[];
assert(sa.stripDrive == result);
} }
@safe unittest @safe unittest