Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions MagicBytesValidator.Tests/Models/AudioFormatMatches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
namespace MagicBytesValidator.Tests.Models;

public class AudioFormatMatches
{
[Fact]
public void Should_match_wav()
{
var wav = new Wav();

// RIFF....WAVE header
var wavTestData = new byte[]
{
0x52, 0x49, 0x46, 0x46, // RIFF
0x24, 0x08, 0x00, 0x00, // file size (arbitrary)
0x57, 0x41, 0x56, 0x45 // WAVE
};

Assert.True(wav.Matches(wavTestData));
}

[Fact]
public void Should_not_match_wav_with_avi_riff()
{
var wav = new Wav();

// RIFF....AVI (not WAVE)
var aviTestData = new byte[]
{
0x52, 0x49, 0x46, 0x46, // RIFF
0x24, 0x08, 0x00, 0x00, // file size
0x41, 0x56, 0x49, 0x20 // AVI
};

Assert.False(wav.Matches(aviTestData));
}

[Fact]
public void Should_not_match_wav_with_invalid_data()
{
var wav = new Wav();

var invalidTestData = new byte[] { 0x00, 0x00, 0x00, 0x00 };

Assert.False(wav.Matches(invalidTestData));
}

[Fact]
public void Should_match_m4a_with_m4a_brand()
{
var m4a = new M4a();

// ftyp box with M4A brand
var m4aTestData = new byte[]
{
0x00, 0x00, 0x00, 0x20, // box size
0x66, 0x74, 0x79, 0x70, // ftyp
0x4D, 0x34, 0x41, 0x20 // M4A
};

Assert.True(m4a.Matches(m4aTestData));
}

[Fact]
public void Should_match_m4a_with_m4b_brand()
{
var m4a = new M4a();

// ftyp box with M4B brand (audiobook variant)
var m4bTestData = new byte[]
{
0x00, 0x00, 0x00, 0x20, // box size
0x66, 0x74, 0x79, 0x70, // ftyp
0x4D, 0x34, 0x42, 0x20 // M4B
};

Assert.True(m4a.Matches(m4bTestData));
}

[Fact]
public void Should_not_match_m4a_with_isom_brand()
{
var m4a = new M4a();

// ftyp box with isom brand (generic MP4 video)
var mp4TestData = new byte[]
{
0x00, 0x00, 0x00, 0x20, // box size
0x66, 0x74, 0x79, 0x70, // ftyp
0x69, 0x73, 0x6F, 0x6D // isom
};

Assert.False(m4a.Matches(mp4TestData));
}

[Fact]
public void Should_match_flac()
{
var flac = new Flac();

// fLaC magic marker followed by metadata block header
var flacTestData = new byte[]
{
0x66, 0x4C, 0x61, 0x43, // fLaC
0x00, 0x00, 0x00, 0x22 // STREAMINFO block header
};

Assert.True(flac.Matches(flacTestData));
}

[Fact]
public void Should_not_match_flac_with_invalid_data()
{
var flac = new Flac();

var invalidTestData = new byte[] { 0x66, 0x4C, 0x00, 0x00 };

Assert.False(flac.Matches(invalidTestData));
}
}
15 changes: 15 additions & 0 deletions MagicBytesValidator/Formats/Flac.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace MagicBytesValidator.Formats;

/// <see href="https://en.wikipedia.org/wiki/FLAC"/>
/// <see href="https://en.wikipedia.org/wiki/List_of_file_signatures"/>
public class Flac : FileByteFilter
{
public Flac() : base(
["audio/flac"],
["flac"]
)
{
// fLaC magic marker
StartsWith([0x66, 0x4C, 0x61, 0x43]);
}
}
18 changes: 18 additions & 0 deletions MagicBytesValidator/Formats/M4a.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace MagicBytesValidator.Formats;

/// <see href="https://en.wikipedia.org/wiki/MPEG-4_Part_14"/>
/// <see href="https://www.garykessler.net/library/file_sigs.html"/>
public class M4a : FileByteFilter
{
public M4a() : base(
["audio/mp4", "audio/x-m4a"],
["m4a"]
)
{
// ftyp box at offset 4, followed by M4A or M4B brand
StartsWithAnyOf([
[null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41, 0x20], // ftypM4A
[null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x42, 0x20], // ftypM4B
]);
}
}
15 changes: 15 additions & 0 deletions MagicBytesValidator/Formats/Wav.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace MagicBytesValidator.Formats;

/// <see href="https://en.wikipedia.org/wiki/WAV"/>
/// <see href="https://en.wikipedia.org/wiki/List_of_file_signatures"/>
public class Wav : FileByteFilter
{
public Wav() : base(
["audio/wav", "audio/x-wav"],
["wav"]
)
{
// RIFF header (52 49 46 46) followed by 4 bytes of file size, then WAVE (57 41 56 45)
StartsWith([0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x41, 0x56, 0x45]);
}
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,13 @@ This can be useful when debugging or validating newly added FileTypes.
| DOCX | docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| DXR | dxr, dcr, dir | application/x-director |
| EXE | exe, com, dll, drv, pif, qts, qtx , sys, acm, ax, cpl, fon, ocx, olb, scr, vbx, vxd, mui, iec, ime, rs, tsp, efi | application/x-dosexec, application/x-msdos-program |
| FLAC | flac | audio/flac |
| GIF | gif | image/gif |
| GZ | gz | application/gzip |
| HEIC | heic, heif | image/heic, image/heif |
| ICO | ico | image/x-icon |
| JPG | jpg, jpeg, jpe, jif, jfif, jfi | image/jpeg |
| M4A | m4a | audio/mp4, audio/x-m4a |
| MIDI | midi, mid | audio/x-midi |
| MP3 | mp3 | audio/mpeg |
| MP4 | mp4 | video/mp4 |
Expand All @@ -285,6 +287,7 @@ This can be useful when debugging or validating newly added FileTypes.
| TIF | tif, tiff | image/tiff |
| TSV | ts, tsv, tsa, mpg, mpeg | video/mp2t |
| TXT | txt | text/plain |
| WAV | wav | audio/wav, audio/x-wav |
| WEBM | mkv, mka, mks, mk3d, webm | video/webm |
| XLS | xls, xla | application/msexcel |
| XLSX | xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
Expand Down
Loading