Add method to determine a file type

This commit is contained in:
jvyden 2021-10-17 20:34:44 -04:00
parent d089cdc60a
commit c84c15fa2c
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
11 changed files with 144 additions and 2 deletions

View file

@ -0,0 +1 @@
FSHbFARC

Binary file not shown.

View file

@ -0,0 +1,3 @@
FSH
this is not my stuff to upload so its just gonna be a file like this for now :/

Binary file not shown.

View file

@ -23,7 +23,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj" /> <ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj" />
<Content Include="ExampleFiles\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -0,0 +1,53 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using ProjectLighthouse.Types.Files;
using Xunit;
namespace ProjectLighthouse.Tests {
public class FileTypeTests {
[Fact]
public void ShouldRecognizeLevel() {
LbpFile file = new(File.ReadAllBytes("ExampleFiles/TestLevel.lvl"));
Assert.True(file.FileType == LbpFileType.Level);
}
[Fact]
public void ShouldRecognizeScript() {
LbpFile file = new(File.ReadAllBytes("ExampleFiles/TestScript.ff"));
Assert.True(file.FileType == LbpFileType.Script);
}
[Fact]
public void ShouldRecognizeTexture() {
LbpFile file = new(File.ReadAllBytes("ExampleFiles/TestTexture.tex"));
Assert.True(file.FileType == LbpFileType.Texture);
}
[Fact]
public void ShouldRecognizeFileArchive() {
LbpFile file = new(File.ReadAllBytes("ExampleFiles/TestFarc.farc"));
Assert.True(file.FileType == LbpFileType.FileArchive);
}
[Fact]
public void ShouldNotRecognizeFileArchiveAsScript() {
LbpFile file = new(File.ReadAllBytes("ExampleFiles/TestFarc.farc"));
Assert.False(file.FileType == LbpFileType.Script);
Assert.True(file.FileType == LbpFileType.FileArchive);
}
[Fact]
public void ShouldRecognizeNothingAsUnknown() {
LbpFile file = new(Array.Empty<byte>());
Assert.True(file.FileType == LbpFileType.Unknown);
}
[Fact]
public void ShouldRecognizeGarbageAsUnknown() {
LbpFile file = new(Encoding.ASCII.GetBytes("free pc only $900"));
Assert.True(file.FileType == LbpFileType.Unknown);
}
}
}

View file

@ -49,6 +49,7 @@ namespace ProjectLighthouse.Controllers {
await database.SaveChangesAsync(); await database.SaveChangesAsync();
slot.LocationId = l.Id; slot.LocationId = l.Id;
slot.CreatorId = user.UserId; slot.CreatorId = user.UserId;
if(slot.BackgroundHash == null) slot.BackgroundHash = "";
database.Slots.Add(slot); database.Slots.Add(slot);
await database.SaveChangesAsync(); await database.SaveChangesAsync();

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -21,5 +22,17 @@ namespace ProjectLighthouse.Helpers {
readByte = reader.ReadByte(); readByte = reader.ReadByte();
} while(readByte != byteToReadTo); } while(readByte != byteToReadTo);
} }
public static byte[] ReadLastBytes(BinaryReader reader, int count, bool restoreOldPosition = true) {
long oldPosition = reader.BaseStream.Position;
if(reader.BaseStream.Length < count) return Array.Empty<byte>();
reader.BaseStream.Position = reader.BaseStream.Length - count;
byte[] data = reader.ReadBytes(count);
if(restoreOldPosition) reader.BaseStream.Position = oldPosition;
return data;
}
} }
} }

View file

@ -0,0 +1,38 @@
using System;
using System.IO;
using System.Text;
using ProjectLighthouse.Types.Files;
namespace ProjectLighthouse.Helpers {
public static class FileHelper {
public static bool IsFileSafe(LbpFile file) {
if(file.FileType == LbpFileType.Unknown) file.FileType = DetermineFileType(file.Data);
return file.FileType switch {
LbpFileType.Texture => true,
LbpFileType.Script => false,
LbpFileType.Level => true,
LbpFileType.FileArchive => false,
LbpFileType.Unknown => false,
_ => throw new ArgumentOutOfRangeException(nameof(file), "Unknown file type."),
};
}
public static LbpFileType DetermineFileType(byte[] data) {
using MemoryStream ms = new(data);
using BinaryReader reader = new(ms);
string footer = Encoding.ASCII.GetString(BinaryHelper.ReadLastBytes(reader, 4));
if(footer == "FARC") return LbpFileType.FileArchive;
byte[] header = reader.ReadBytes(3);
return Encoding.ASCII.GetString(header) switch {
"TEX" => LbpFileType.Texture,
"FSH" => LbpFileType.Script,
"LVL" => LbpFileType.Level,
_ => LbpFileType.Unknown,
};
}
}
}

View file

@ -0,0 +1,22 @@
using System.IO;
using ProjectLighthouse.Helpers;
namespace ProjectLighthouse.Types.Files {
public class LbpFile {
public LbpFile(byte[] data) {
this.Data = data;
this.FileType = FileHelper.DetermineFileType(data);
}
/// <summary>
/// The type of file.
/// </summary>
public LbpFileType FileType;
/// <summary>
/// A buffer of the file's data.
/// </summary>
public readonly byte[] Data;
}
}

View file

@ -0,0 +1,9 @@
namespace ProjectLighthouse.Types.Files {
public enum LbpFileType {
Script, // .ff, FSH
Texture, // TEX
Level, // LVL
FileArchive, // .farc, (ends with FARC)
Unknown,
}
}