diff --git a/src/LibHac/Fs/Fsa/MountUtility.cs b/src/LibHac/Fs/Fsa/MountUtility.cs
index f7fb917f..b7a144ea 100644
--- a/src/LibHac/Fs/Fsa/MountUtility.cs
+++ b/src/LibHac/Fs/Fsa/MountUtility.cs
@@ -23,7 +23,7 @@ public static class MountUtility
///
/// If the method returns successfully, contains the mount name of the provided path;
/// otherwise the contents are undefined.
- /// If the method returns successfully, contains the provided path without the
+ /// If the method returns successfully, contains the provided path without the
/// mount name; otherwise the contents are undefined.
/// The to process.
/// : The operation was successful.
@@ -31,52 +31,58 @@ public static class MountUtility
/// the mount name that begins with / or \.
/// : contains an invalid mount name
/// or does not have a mount name.
- 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)
diff --git a/tests/LibHac.Tests/Fs/FsaTests/MountUtilityTests.cs b/tests/LibHac.Tests/Fs/FsaTests/MountUtilityTests.cs
new file mode 100644
index 00000000..371e3236
--- /dev/null
+++ b/tests/LibHac.Tests/Fs/FsaTests/MountUtilityTests.cs
@@ -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()));
+ }
+}
\ No newline at end of file