mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add some validation to StorageBase
This commit is contained in:
parent
54950c9b68
commit
bfc343e801
9 changed files with 89 additions and 40 deletions
|
@ -55,7 +55,7 @@ namespace LibHac.Fs
|
|||
|
||||
public Result GetSize(out long size)
|
||||
{
|
||||
size = 0;
|
||||
size = default;
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return GetSizeImpl(out size);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace LibHac.Fs
|
|||
FsClient = Handle.File.Parent.FsClient;
|
||||
}
|
||||
|
||||
public override Result Read(long offset, Span<byte> destination)
|
||||
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
|
@ -30,14 +30,13 @@ namespace LibHac.Fs
|
|||
Result rc = UpdateSize();
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (destination.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
||||
if (!IsRangeValid(offset, destination.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
return FsClient.ReadFile(Handle, offset, destination);
|
||||
}
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
|
@ -46,26 +45,25 @@ namespace LibHac.Fs
|
|||
Result rc = UpdateSize();
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (source.Length < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
||||
if (!IsRangeValid(offset, source.Length, FileSize)) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
return FsClient.WriteFile(Handle, offset, source);
|
||||
}
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return FsClient.FlushFile(Handle);
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
FileSize = InvalidSize;
|
||||
|
||||
return FsClient.SetFileSize(Handle, size);
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = default;
|
||||
|
||||
|
@ -87,7 +85,7 @@ namespace LibHac.Fs
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (CloseHandle)
|
||||
{
|
||||
|
|
|
@ -205,8 +205,8 @@ namespace LibHac.Fs
|
|||
{
|
||||
None = 0,
|
||||
Application = 1 << 0,
|
||||
Internal = 1 << 1,
|
||||
All = Application | Internal
|
||||
System = 1 << 1,
|
||||
All = Application | System
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
|
||||
public static Result RemapStorageMapFull => new Result(ModuleFs, 6811);
|
||||
|
||||
public static Result Result6902 => new Result(ModuleFs, 6902);
|
||||
public static Result SubStorageNotInitialized => new Result(ModuleFs, 6902);
|
||||
public static Result MountNameNotFound => new Result(ModuleFs, 6905);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace LibHac.Fs
|
|||
public static Result CreateSystemSaveData(this FileSystemClient fs, SaveDataSpaceId spaceId,
|
||||
ulong saveDataId, UserId userId, ulong ownerId, long size, long journalSize, uint flags)
|
||||
{
|
||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.Internal,
|
||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
|
||||
() =>
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
@ -89,7 +89,7 @@ namespace LibHac.Fs
|
|||
|
||||
public static Result DeleteSaveData(this FileSystemClient fs, ulong saveDataId)
|
||||
{
|
||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.Internal,
|
||||
return fs.RunOperationWithAccessLog(LocalAccessLogMode.System,
|
||||
() =>
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
|
|
@ -1,20 +1,71 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
public abstract class StorageBase : IStorage
|
||||
{
|
||||
public abstract Result Read(long offset, Span<byte> destination);
|
||||
public abstract Result Write(long offset, ReadOnlySpan<byte> source);
|
||||
public abstract Result Flush();
|
||||
public abstract Result SetSize(long size);
|
||||
public abstract Result GetSize(out long size);
|
||||
// 0 = not disposed; 1 = disposed
|
||||
private int _disposedState;
|
||||
private bool IsDisposed => _disposedState != 0;
|
||||
|
||||
public virtual void Dispose() { }
|
||||
public abstract Result ReadImpl(long offset, Span<byte> destination);
|
||||
public abstract Result WriteImpl(long offset, ReadOnlySpan<byte> source);
|
||||
public abstract Result FlushImpl();
|
||||
public abstract Result GetSizeImpl(out long size);
|
||||
public abstract Result SetSizeImpl(long size);
|
||||
|
||||
public Result Read(long offset, Span<byte> destination)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return ReadImpl(offset, destination);
|
||||
}
|
||||
|
||||
public Result Write(long offset, ReadOnlySpan<byte> source)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return WriteImpl(offset, source);
|
||||
}
|
||||
|
||||
public Result Flush()
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return FlushImpl();
|
||||
}
|
||||
|
||||
public Result SetSize(long size)
|
||||
{
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return SetSizeImpl(size);
|
||||
}
|
||||
|
||||
public Result GetSize(out long size)
|
||||
{
|
||||
size = default;
|
||||
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
|
||||
|
||||
return GetSizeImpl(out size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Make sure Dispose is only called once
|
||||
if (Interlocked.CompareExchange(ref _disposedState, 1, 0) == 0)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
|
||||
public static bool IsRangeValid(long offset, long size, long totalSize)
|
||||
{
|
||||
return size <= totalSize && offset <= totalSize - size;
|
||||
return offset >= 0 && size >= 0 && size <= totalSize && offset <= totalSize - size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,38 +23,38 @@ namespace LibHac.Fs
|
|||
Size = size;
|
||||
}
|
||||
|
||||
public override Result Read(long offset, Span<byte> destination)
|
||||
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||
{
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
if (destination.Length == 0) return Result.Success;
|
||||
if (Size < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
if (!IsRangeValid(offset, destination.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
return BaseStorage.Read(Offset + offset, destination);
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||
{
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
if (source.Length == 0) return Result.Success;
|
||||
if (Size < 0 || offset < 0) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
if (!IsRangeValid(offset, source.Length, Size)) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
return BaseStorage.Write(Offset + offset, source);
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
||||
if (size < 0 || Offset < 0) return ResultFs.ValueOutOfRange.Log();
|
||||
if (size < 0 || Offset < 0) return ResultFs.InvalidSize.Log();
|
||||
|
||||
Result rc = BaseStorage.GetSize(out long baseSize);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
@ -72,11 +72,11 @@ namespace LibHac.Fs
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = default;
|
||||
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
|
||||
size = Size;
|
||||
return Result.Success;
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace LibHac.FsService.Creators
|
|||
imageHash.CopyTo(ImageHash);
|
||||
}
|
||||
|
||||
public override Result Read(long offset, Span<byte> destination)
|
||||
public override Result ReadImpl(long offset, Span<byte> destination)
|
||||
{
|
||||
// In secure mode, if Handle is old and the card's device ID and
|
||||
// header hash are still the same, Handle is updated to the new handle
|
||||
|
@ -95,22 +95,22 @@ namespace LibHac.FsService.Creators
|
|||
return GameCard.Read(Handle, offset, destination);
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationInRoGameCardStorageWrite.Log();
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationInRoGameCardStorageSetSize.Log();
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = 0;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace LibHac.FsSystem
|
|||
|
||||
public override Result SetSize(long size)
|
||||
{
|
||||
if (BaseStorage == null) return ResultFs.Result6902.Log();
|
||||
if (BaseStorage == null) return ResultFs.SubStorageNotInitialized.Log();
|
||||
|
||||
// todo: Add IsResizable member
|
||||
// if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
||||
|
|
Loading…
Reference in a new issue