Merge pull request #124 from Thealexbarney/path-fixes

Fix some path parsing
This commit is contained in:
Alex Barney 2020-03-23 16:12:37 -07:00 committed by GitHub
commit 3cd53a7de3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 50 deletions

View file

@ -124,13 +124,11 @@ namespace LibHacBuild.CodeGen
{
foreach (ModuleInfo module in modules)
{
var set = new HashSet<long>();
var set = new HashSet<int>();
foreach (ResultInfo result in module.Results)
{
long description = (long)result.DescriptionStart << 32 | (uint)result.DescriptionEnd;
if (!set.Add(description))
if (!set.Add(result.DescriptionStart))
{
throw new InvalidDataException($"Duplicate result {result.Module}-{result.DescriptionStart}-{result.DescriptionEnd}.");
}

View file

@ -124,11 +124,12 @@ Module,DescriptionStart,DescriptionEnd,Name,Summary
2,4748,,AesXtsFileHeaderInvalidKeysInSetSize,
2,4761,4769,SaveDataTransferDataCorrupted,
2,4771,4779,SignedSystemPartitionDataCorrupted,
2,4781,,GameCardLogoDataCorrupted,
2,4791,4799,MultiCommitContextCorrupted,
2,4791,,InvalidMultiCommitContextVersion,The version of the multi-commit context file is to high for the current MultiCommitManager implementation.
2,4790,4799,MultiCommitContextCorrupted,
2,4791,,InvalidMultiCommitContextVersion,The version of the multi-commit context file is too high for the current MultiCommitManager implementation.
2,4792,,InvalidMultiCommitContextState,The multi-commit has not been provisionally committed.
# The range name is a guess. 4812 is currently the only result in it

1 Module,DescriptionStart,DescriptionEnd,Name,Summary
124 2,6005,,InvalidPathFormat,
125 2,6006,,DirectoryUnobtainable,
126 2,6007,,NotNormalized,
127 2,6030,6059,InvalidPathForOperation,
128 2,6030,6059,InvalidPathForOperation, 2,6031,,DirectoryNotDeletable,
129 2,6031,,DirectoryNotDeletable, 2,6032,,DestinationIsSubPathOfSource,
130 2,6032,,DestinationIsSubPathOfSource, 2,6033,,PathNotFoundInSaveDataFileTable,
131 2,6033,,PathNotFoundInSaveDataFileTable, 2,6034,,DifferentDestFileSystem,
132 2,6034,,DifferentDestFileSystem, 2,6061,,InvalidOffset,
133 2,6061,,InvalidOffset, 2,6062,,InvalidSize,
134 2,6062,,InvalidSize, 2,6063,,NullptrArgument,
135 2,6063,,NullptrArgument, 2,6064,,InvalidAlignment,

View file

@ -256,9 +256,9 @@ namespace LibHac.Fs
/// <summary>Error code: 2002-4781; Inner value: 0x255a02</summary>
public static Result.Base GameCardLogoDataCorrupted => new Result.Base(ModuleFs, 4781);
/// <summary>Error code: 2002-4791; Range: 4791-4799; Inner value: 0x256e02</summary>
public static Result.Base MultiCommitContextCorrupted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 4791, 4799); }
/// <summary>The version of the multi-commit context file is to high for the current MultiCommitManager implementation.<br/>Error code: 2002-4791; Inner value: 0x256e02</summary>
/// <summary>Error code: 2002-4790; Range: 4790-4799; Inner value: 0x256c02</summary>
public static Result.Base MultiCommitContextCorrupted { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 4790, 4799); }
/// <summary>The version of the multi-commit context file is too high for the current MultiCommitManager implementation.<br/>Error code: 2002-4791; Inner value: 0x256e02</summary>
public static Result.Base InvalidMultiCommitContextVersion => new Result.Base(ModuleFs, 4791);
/// <summary>The multi-commit has not been provisionally committed.<br/>Error code: 2002-4792; Inner value: 0x257002</summary>
public static Result.Base InvalidMultiCommitContextState => new Result.Base(ModuleFs, 4792);

View file

@ -27,7 +27,7 @@ namespace LibHac.FsSystem
_path = path;
_offset = 0;
_length = 0;
_finished = path.Length == 1;
_finished = path.Length == 1 || path[1] == '\0';
}
/// <summary>
@ -57,12 +57,12 @@ namespace LibHac.FsSystem
_offset = _offset + _length + 1;
int end = _offset;
while (end < _path.Length && _path[end] != '/')
while (end < _path.Length && _path[end] != '\0' && _path[end] != '/')
{
end++;
}
_finished = end + 1 >= _path.Length;
_finished = end + 1 >= _path.Length || _path[end + 1] == '\0';
_length = end - _offset;
return true;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Fs;
namespace LibHac.FsSystem.Save
@ -44,7 +45,7 @@ namespace LibHac.FsSystem.Save
ReadEntry(index, out entry);
if (entry.Parent == key.Parent && Util.StringSpansEqual(name, key.Name))
if (entry.Parent == key.Parent && StringUtils.Compare(name, key.Name) == 0)
{
return (index, prevIndex);
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
@ -47,7 +48,11 @@ namespace LibHac
foreach (ref readonly Element element in elements)
{
var result = new Result(element.Module, element.DescriptionStart);
dict.Add(result, GetName(element.NameOffset).ToString());
if (!dict.TryAdd(result, GetName(element.NameOffset).ToString()))
{
throw new InvalidDataException("Invalid result name archive: Duplicate result found.");
}
}
return dict;

View file

@ -64,42 +64,6 @@ namespace LibHac
return true;
}
/// <summary>
/// Compares two strings stored int byte spans. For the strings to be equal,
/// they must terminate in the same place.
/// A string can be terminated by either a null character or the end of the span.
/// </summary>
/// <param name="s1">The first string to be compared.</param>
/// <param name="s2">The first string to be compared.</param>
/// <returns><see langword="true"/> if the strings are equal;
/// otherwise <see langword="false"/>.</returns>
public static bool StringSpansEqual(ReadOnlySpan<byte> s1, ReadOnlySpan<byte> s2)
{
// Make s1 the long string for simplicity
if (s1.Length < s2.Length)
{
ReadOnlySpan<byte> tmp = s1;
s1 = s2;
s2 = tmp;
}
int shortLength = s2.Length;
int i;
for (i = 0; i < shortLength; i++)
{
if (s1[i] != s2[i]) return false;
// Both strings are null-terminated
if (s1[i] == 0) return true;
}
// The bytes in the short string equal those in the long.
// Check if the strings are the same length or if the next
// character in the long string is a null character
return s1.Length == s2.Length || s1[i] == 0;
}
public static ReadOnlySpan<byte> GetUtf8Bytes(string value)
{
return Encoding.UTF8.GetBytes(value).AsSpan();