Match AGE RIFF decode boundaries

This commit is contained in:
gamer147
2026-07-29 18:35:21 -04:00
parent da7e0e25ce
commit 32c5d1e901
6 changed files with 105 additions and 16 deletions

View File

@@ -15,7 +15,7 @@ public class RiffWaveSanitizerTests
byte[] data = { 1, 2, 3 };
byte[] source = Wave(("fmt ", fmt), ("LIST", info), ("smpl", sampleLoop), ("data", data));
byte[] sanitized = RiffWaveSanitizer.RemoveInfoMetadata(source);
byte[] sanitized = RiffWaveSanitizer.PrepareForGodot(source);
Assert.NotSame(source, sanitized);
Assert.Equal(sanitized.Length - 8, BinaryPrimitives.ReadInt32LittleEndian(sanitized.AsSpan(4, 4)));
@@ -30,7 +30,21 @@ public class RiffWaveSanitizerTests
{
byte[] source = Wave(("fmt ", new byte[] { 1, 0 }), ("data", new byte[] { 1, 2 }));
Assert.Same(source, RiffWaveSanitizer.RemoveInfoMetadata(source));
Assert.Same(source, RiffWaveSanitizer.PrepareForGodot(source));
}
[Fact]
public void DropsBytesAfterFirstDeclaredRiffExtent()
{
byte[] first = Wave(("fmt ", new byte[] { 1, 0 }), ("data", new byte[] { 1, 2, 3, 4 }));
byte[] second = Wave(("fmt ", new byte[] { 1, 0 }), ("data", new byte[] { 5, 6 }));
byte[] separator = Encoding.ASCII.GetBytes("Content-Disposition: form-data\r\n\r\n");
byte[] source = [.. first, .. separator, .. second];
byte[] sanitized = RiffWaveSanitizer.PrepareForGodot(source);
Assert.NotSame(source, sanitized);
Assert.Equal(first, sanitized);
}
[Fact]
@@ -39,7 +53,7 @@ public class RiffWaveSanitizerTests
var resources = ResourceMap.Load();
AudioPayload audio = resources.ReadAudio(resources.ResolveSoundEffect(0x28)!);
byte[] sanitized = RiffWaveSanitizer.RemoveInfoMetadata(audio.Bytes);
byte[] sanitized = RiffWaveSanitizer.PrepareForGodot(audio.Bytes);
Assert.Equal("E0808.WAV", audio.Name);
Assert.Equal(688_570, audio.Bytes.Length);
@@ -48,6 +62,23 @@ public class RiffWaveSanitizerTests
Assert.Equal(Chunk(audio.Bytes, "data"), Chunk(sanitized, "data"));
}
[Fact]
public void InstalledFirstBossSoundStopsAtFirstDeclaredRiff()
{
var resources = ResourceMap.Load();
AudioPayload audio = resources.ReadAudio(resources.ResolveSoundEffect(0x125)!);
byte[] sanitized = RiffWaveSanitizer.PrepareForGodot(audio.Bytes);
Assert.Equal("A1215.WAV", audio.Name);
Assert.Equal(323_009, audio.Bytes.Length);
Assert.Equal(157_940, sanitized.Length);
Assert.Equal(157_940,
8 + BinaryPrimitives.ReadInt32LittleEndian(sanitized.AsSpan(4, 4)));
Assert.Equal(157_896, Chunk(sanitized, "data").Length);
Assert.Equal(audio.Bytes.AsSpan(0, sanitized.Length).ToArray(), sanitized);
}
private static byte[] Wave(params (string Id, byte[] Payload)[] chunks)
{
int length = 12 + chunks.Sum(chunk => 8 + chunk.Payload.Length + (chunk.Payload.Length & 1));