mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fix an off-by-one error when parsing mount names
This commit is contained in:
parent
2e04bcad94
commit
dfd37d314f
2 changed files with 61 additions and 20 deletions
|
@ -23,7 +23,7 @@ public static class MountUtility
|
|||
/// </summary>
|
||||
/// <param name="mountName">If the method returns successfully, contains the mount name of the provided path;
|
||||
/// otherwise the contents are undefined.</param>
|
||||
/// <param name="subPath">If the method returns successfully, contains the provided path without the
|
||||
/// <param name="outSubPath">If the method returns successfully, contains the provided path without the
|
||||
/// mount name; otherwise the contents are undefined.</param>
|
||||
/// <param name="path">The <see cref="Path"/> to process.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
|
@ -31,52 +31,58 @@ public static class MountUtility
|
|||
/// the mount name that begins with <c>/</c> or <c>\</c>.<br/>
|
||||
/// <see cref="ResultFs.InvalidMountName"/>: <paramref name="path"/> contains an invalid mount name
|
||||
/// or does not have a mount name.</returns>
|
||||
private static Result GetMountNameAndSubPath(out MountName mountName, out U8Span subPath, U8Span path)
|
||||
private static Result GetMountNameAndSubPath(out MountName mountName, out U8Span outSubPath, U8Span path)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out mountName);
|
||||
subPath = default;
|
||||
|
||||
int mountLen = 0;
|
||||
int maxMountLen = Math.Min(path.Length, PathTool.MountNameLengthMax);
|
||||
outSubPath = default;
|
||||
|
||||
if (WindowsPath.IsWindowsDrive(path) || WindowsPath.IsUncPath(path))
|
||||
{
|
||||
StringUtils.Copy(mountName.Name, HostRootFileSystemMountName);
|
||||
mountName.Name[PathTool.MountNameLengthMax] = NullTerminator;
|
||||
|
||||
subPath = path;
|
||||
outSubPath = path;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= maxMountLen; i++)
|
||||
{
|
||||
if (path[i] == DriveSeparator)
|
||||
{
|
||||
mountLen = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int mountLen = FindMountNameDriveSeparator(path);
|
||||
|
||||
if (mountLen == 0)
|
||||
return ResultFs.InvalidMountName.Log();
|
||||
|
||||
if (mountLen > maxMountLen)
|
||||
if (mountLen > PathTool.MountNameLengthMax)
|
||||
return ResultFs.InvalidMountName.Log();
|
||||
|
||||
if (mountLen <= 0)
|
||||
return ResultFs.InvalidMountName.Log();
|
||||
|
||||
U8Span subPathTemp = path.Slice(mountLen + 1);
|
||||
U8Span subPath = path.Slice(mountLen + 1);
|
||||
|
||||
if (subPathTemp.Length == 0 ||
|
||||
(subPathTemp[0] != DirectorySeparator && subPathTemp[0] != AltDirectorySeparator))
|
||||
bool startsWithDir = subPath.Length > 0 &&
|
||||
(subPath[0] == DirectorySeparator || subPath[0] == AltDirectorySeparator);
|
||||
|
||||
if (!startsWithDir)
|
||||
return ResultFs.InvalidPathFormat.Log();
|
||||
|
||||
path.Value.Slice(0, mountLen).CopyTo(mountName.Name);
|
||||
mountName.Name[mountLen] = NullTerminator;
|
||||
subPath = subPathTemp;
|
||||
|
||||
outSubPath = subPath;
|
||||
return Result.Success;
|
||||
|
||||
static int FindMountNameDriveSeparator(U8Span path)
|
||||
{
|
||||
for (int i = 0; i < path.Length && i < PathTool.MountNameLengthMax + 1; i++)
|
||||
{
|
||||
if (path[i] == NullTerminator)
|
||||
return 0;
|
||||
|
||||
if (path[i] == DriveSeparator)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsValidMountName(this FileSystemClientImpl fs, U8Span name)
|
||||
|
|
35
tests/LibHac.Tests/Fs/FsaTests/MountUtilityTests.cs
Normal file
35
tests/LibHac.Tests/Fs/FsaTests/MountUtilityTests.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.Tests.Fs.FileSystemClientTests;
|
||||
using Xunit;
|
||||
|
||||
namespace LibHac.Tests.Fs.FsaTests;
|
||||
|
||||
public class MountUtilityTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("0123456789ABCDE", "0123456789ABCDE:/")]
|
||||
[InlineData("01234", "01234:/")]
|
||||
public void GetMountName_ValidName_ReturnsSuccess(string mountName, string path)
|
||||
{
|
||||
FileSystemClient fs = FileSystemServerFactory.CreateClient(true);
|
||||
|
||||
Assert.Success(fs.MountSdCard(mountName.ToU8Span()));
|
||||
Assert.Success(fs.GetEntryType(out _, path.ToU8Span()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("01234", "01234")]
|
||||
[InlineData("0123456789ABCDE", "0123456789ABCDE")]
|
||||
[InlineData("01234", "0123456789ABCDEF")]
|
||||
[InlineData("01234", "0123456789ABCDEF:/")]
|
||||
public void GetMountName_InvalidName_ReturnsInvalidMountName(string mountName, string path)
|
||||
{
|
||||
FileSystemClient fs = FileSystemServerFactory.CreateClient(true);
|
||||
|
||||
Assert.Success(fs.MountSdCard(mountName.ToU8Span()));
|
||||
Assert.Result(ResultFs.InvalidMountName, fs.GetEntryType(out _, path.ToU8Span()));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue