diff --git a/LICENSE b/LICENSE index aa148a6..95b9285 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright © 2025 traperto GmbH +Copyright © 2026 traperto GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/MagicBytesValidator.Tests/MagicBytesValidator.Tests.csproj b/MagicBytesValidator.Tests/MagicBytesValidator.Tests.csproj index 90615fe..077cf8f 100644 --- a/MagicBytesValidator.Tests/MagicBytesValidator.Tests.csproj +++ b/MagicBytesValidator.Tests/MagicBytesValidator.Tests.csproj @@ -5,9 +5,9 @@ - + - + all runtime; build; native; contentfiles; analyzers diff --git a/MagicBytesValidator.Tests/MappingRegister.cs b/MagicBytesValidator.Tests/MappingRegister.cs index d59a48e..0b3772f 100644 --- a/MagicBytesValidator.Tests/MappingRegister.cs +++ b/MagicBytesValidator.Tests/MappingRegister.cs @@ -19,19 +19,13 @@ public void Should_register_single_filetype() [Fact] public void Should_register_list_filetype() { - var cusDbcLaikaFileType = new TestFileType( - ["traperto/laikaschmidt"], - ["ls"] - ).StartsWith([0x6e, 0x69, 0x6b, 0x6c, 0x61, 0x73, 0x73, 0x63, 0x68, 0x6d, 0x69, 0x64, 0x74]); - var kryptobiFileType = new TestFileType( ["traperto/tobiasjanssen"], ["tjn"] ).StartsWith([0x74, 0x6f, 0x62, 0x69, 0x61, 0x73, 0x6a, 0x61, 0x6e, 0x73, 0x73, 0x65, 0x6e]); - _mapping.Register([cusDbcLaikaFileType, kryptobiFileType]); + _mapping.Register([kryptobiFileType]); Assert.Contains(kryptobiFileType, _mapping.FileTypes); - Assert.Contains(cusDbcLaikaFileType, _mapping.FileTypes); } [Fact] diff --git a/MagicBytesValidator.Tools/Program.cs b/MagicBytesValidator.Tools/Program.cs index 17cf441..2dcd05b 100644 --- a/MagicBytesValidator.Tools/Program.cs +++ b/MagicBytesValidator.Tools/Program.cs @@ -50,7 +50,7 @@ private static void PrintHelp() - help Shows this help - (traperto GmbH, 2024) + (traperto GmbH, 2026) """); } } \ No newline at end of file diff --git a/MagicBytesValidator/MagicBytesValidator.csproj b/MagicBytesValidator/MagicBytesValidator.csproj index ca22296..065c694 100644 --- a/MagicBytesValidator/MagicBytesValidator.csproj +++ b/MagicBytesValidator/MagicBytesValidator.csproj @@ -9,7 +9,7 @@ https://github.com/Traperto/magic-bytes-validator/blob/main/README.md mime mimetype mimetypes magic magicbyte magicbytes extension extensions file fileextension traperto trapertoGmbh - TobiasJanssen LaikaSchmidt MaximilianBreuker + TobiasJanssen MaximilianBreuker https://github.com/Traperto/magic-bytes-validator README.md diff --git a/README.md b/README.md index 0aa243d..2723b7f 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,100 @@ # MagicBytesValidator + Recognize file types from `Stream`s or `IFormFile`s using MIME types or file extensions and validate them against the magic bytes according to the file types. -The existing `IFileType`s can be expanded in various ways. +The existing file types can be expanded in various ways. -### How to install? +### How to install - Install nuget package into your project: -```powershell -Install-Package MagicBytesValidator -Version 2.1.6 -``` + ```powershell + Install-Package MagicBytesValidator -Version 2.1.6 + ``` -```bash -dotnet add package MagicBytesValidator --version 2.1.6 -``` + ```bash + dotnet add package MagicBytesValidator --version 2.1.6 + ``` - Reference in your csproj: -```xml - -``` - -### How to use it? - -- Create new instances of the validator and providers: -```c# -var validator = new MagicBytesValidator.Services.Validator(); -var formFileTypeProvider = new MagicBytesValidator.Services.Http.FormFileTypeProvider(); -var streamFileTypeProvider = new MagicBytesValidator.Services.Streams.StreamFileTypeProvider(); -``` - -- Find a file type by extension or MIME type: -```c# -var pngFileType = validator.Mapping.FindByExtension("png"); -var pdfFileType = validator.Mapping.FindByMimeType("application/pdf"); -``` -- Determine and validate a file type by uploaded IFormFile: -```c# -var fileType = await formFileTypeProvider.FindValidatedTypeAsync(formFile, null, CancellationToken.None); -``` - -- Determine the file type of a file by its stream -```c# -var fileType = await streamFileTypeProvider.TryFindUnambiguousAsync(fileStream, CancellationToken.None); -``` - -- Check a file with its stream and file type: -```c# -var isValid = await validator.IsValidAsync(memoryStream, fileType, CancellationToken.None); -``` + ```xml + + ``` + +### How to use + +- Check if a stream content matches a file type: + + ```c# + var validator = new MagicBytesValidator.Services.Validator(); + var pngFileType = validator.Mapping.FindByExtension("png"); + + var isValidPng = await validator.IsValidAsync(memoryStream, pngFileType, CancellationToken.None); + ``` + +- Determine and validate a file type by uploaded `IFormFile`: + + ```c# + var formFileTypeProvider = new MagicBytesValidator.Services.Http.FormFileTypeProvider(); + + try { + var fileType = await formFileTypeProvider.FindValidatedTypeAsync(formFile, null, CancellationToken.None); + + if (fileType is not null) { + // Further code + } { + // Can't determine type + } + } catch(MagicBytesValidator.Exceptions.Http.MimeTypeMismatchException) { + // Content and given MIME type / extension don't match. + } + ``` + +- Determine the file type of a file by its stream: + + ```c# + var streamFileTypeProvider = new MagicBytesValidator.Services.Streams.StreamFileTypeProvider(); + var fileType = await streamFileTypeProvider.TryFindUnambiguousAsync(fileStream, CancellationToken.None); + + if (fileType is not null) { + // Further code + } else { + // Can't determine unambiguous type + } + ``` + +#### Add custom file types + +- Register a custom type with filters: + + ```c# + public class CustomType : MagicBytesValidator.Models.FileByteFilter + { + public CustomType() : base( + ["traperto/trp"], // mime types + ["trp"] // extensions + ) + { + // defined magic byte sequences + StartsWith([ + 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65 + ]) + .EndsWith([ + 0xFF, 0xFF + ]) + .Specific(new ByteCheck(512, [0xFD])); // offset: 512 bytes, negative offset looks for a specific offset from the end of file + } + } + + var mapping = new MagicBytesValidator.Services.Mapping(); + mapping.Register(new CustomType()); + mapping.Register(new[] { new CustomType() }); // Add multiple types + + // Registering all `IFileType`s of the given assembly that are also not abstract and have an empty constructor. + _mapping.Register(typeof(CustomType).Assembly); + ``` + +### CLI tool -#### Expand the file type mapping - -- Get mapping: -```c# -// use the validator: -var mapping = validator.Mapping; - -// use the formFileTypeProvider: -var mapping = formFileTypeProvider.Mapping; - -// or create a new instance of the mapping: -var mapping = new MagicBytesValidator.Services.Mapping(); -``` - -- Register a single `FileByteFilter`: -```c# -mapping.Register( - new FileByteFilter( - "traperto/trp", // MIME type - new[] { "trp" } // file extensions - ) { - // magic byte sequences - StartsWith([ - 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65 - ]) - .EndsWith([ - 0xFF, 0xFF - ]) - } -) -``` - -- `FileByteFilter`s with specific offset checks: -```c# -mapping.Register( - new FileByteFilter( - "traperto/trp", // MIME type - new[] { "trp" } // file extensions - ) { - // magic byte sequences - Specific(new ByteCheck(512, [0xFD])); - } -) -``` -`ByteCheck` allows for negative offset values to look for a specific offset counting from the end of file. - -- Register a list of filetypes: -```c# -mapping.Register(listOfFileTypes); -``` - -You can also create variants of `IFileType` and register them by passing the Assembly of the new `IFileType`s, e.g. -`mapping.Register(typeof(CustomFileType).Assembly);`. This will register all `IFileType`s of the given assembly that are also not abstract and have an empty constructor. - -```c# -public class CustomFileType : FileTypeWithStartSequences -{ - public CustomFileType() : base( - "traperto/trp", // MIME type - new[] { "trp" }, // file extensions - new[] { // magic byte sequences - new byte[] { 0x74, 0x72, 0x61, 0x70, 0x65, 0x72, 0x74, 0x6f } - } - ) - { - } -} - -var assembly = typeof(CustomFileType).Assembly; -_mapping.Register(assembly); -``` - -### CLI There's a CLI tool (_MagicBytesValidator.CLI_) which can be used to determine MIME types for a local file by calling the following command: @@ -132,63 +106,63 @@ This can be useful when debugging or validating newly added FileTypes. ### List of file types -|FileType|Extensions|MIME Types| -|-|-|-| -|AIF|aif, aiff, aifc|audio/x-aiff| -|BIN|bin, file, com, class, ini|application/octet-stream| -|BMP|bmp|image/bmp| -|CAB|cab|application/vnd.ms-cab-compressed, application/x-cab-compressed| -|DOC|doc, dot|application/msword| -|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| -|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| -|MIDI|midi, mid|audio/x-midi| -|MP3|mp3|audio/mpeg| -|MP4|mp4|video/mp4| -|MPG|mpg, mpeg, mpe, m2p, vob|video/mpeg| -|ODP|odp|application/vnd.oasis.opendocument.presentation| -|ODS|ods|application/vnd.oasis.opendocument.spreadsheet| -|ODT|odt|application/vnd.oasis.opendocument.text| -|OGV|ogv, ogg, oga|video/ogg| -|PBM|pbm|image/x-portable-bitmap| -|PDF|pdf|application/pdf| -|PGM|pgm|image/x-portable-graymap| -|PNG|png|image/png| -|PPM|ppm|image/x-portable-pixmap| -|PPT|ppt, ppz, pps, pot|application/mspowerpoint, application/vnd.ms-powerpoint| -|PPTX|pptx|application/vnd.openxmlformats-officedocument.presentationml.presentation| -|RAR|rar|application/vnd.rar, application/x-rar-compressed| -|RPM|rpm|application/x-rpm, application/x-redhat-package-manager| -|RTF|rtf|application/rtf| -|SND|snd, au|audio/basic| -|SVG|svg, svgz|image/svg+xml| -|SWF|swf|application/x-shockwave-flash| -|3GP|3gp|video/3gpp| -|TIF|tif, tiff|image/tiff| -|TSV|ts, tsv, tsa, mpg, mpeg|video/mp2t| -|TXT|txt|text/plain| -|WEBM|mkv, mka, mks, mk3d, webm|video/webm| -|XLS|xls, xla|application/msexcel| -|XLSX|xlsx|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet| -|XML|xml|application/xml, text/xml| -|Z|z|application/x-compress| -|ZIP|zip|application/zip, application/x-zip-compressed| - -### What is the licence? +| FileType | Extensions | MIME Types | +| -------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| AIF | aif, aiff, aifc | audio/x-aiff | +| BIN | bin, file, com, class, ini | application/octet-stream | +| BMP | bmp | image/bmp | +| CAB | cab | application/vnd.ms-cab-compressed, application/x-cab-compressed | +| DOC | doc, dot | application/msword | +| 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 | +| 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 | +| MIDI | midi, mid | audio/x-midi | +| MP3 | mp3 | audio/mpeg | +| MP4 | mp4 | video/mp4 | +| MPG | mpg, mpeg, mpe, m2p, vob | video/mpeg | +| ODP | odp | application/vnd.oasis.opendocument.presentation | +| ODS | ods | application/vnd.oasis.opendocument.spreadsheet | +| ODT | odt | application/vnd.oasis.opendocument.text | +| OGV | ogv, ogg, oga | video/ogg | +| PBM | pbm | image/x-portable-bitmap | +| PDF | pdf | application/pdf | +| PGM | pgm | image/x-portable-graymap | +| PNG | png | image/png | +| PPM | ppm | image/x-portable-pixmap | +| PPT | ppt, ppz, pps, pot | application/mspowerpoint, application/vnd.ms-powerpoint | +| PPTX | pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | +| RAR | rar | application/vnd.rar, application/x-rar-compressed | +| RPM | rpm | application/x-rpm, application/x-redhat-package-manager | +| RTF | rtf | application/rtf | +| SND | snd, au | audio/basic | +| SVG | svg, svgz | image/svg+xml | +| SWF | swf | application/x-shockwave-flash | +| 3GP | 3gp | video/3gpp | +| TIF | tif, tiff | image/tiff | +| TSV | ts, tsv, tsa, mpg, mpeg | video/mp2t | +| TXT | txt | text/plain | +| WEBM | mkv, mka, mks, mk3d, webm | video/webm | +| XLS | xls, xla | application/msexcel | +| XLSX | xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | +| XML | xml | application/xml, text/xml | +| Z | z | application/x-compress | +| ZIP | zip | application/zip, application/x-zip-compressed | + +### License [MIT License](./LICENSE) ``` -▓▓ ▓▓▓▓▓▓▓▓▓▓ -▓▓ ▓▓ -▓▓▓▓▓▓▓▓▓ ▓▓ -▓▓ ▓▓ traperto GmbH -▓▓ ▓▓▓▓▓▓▓▓▓▓ +▓▓ ▓▓▓▓▓▓▓▓▓ +▓▓ ▓▓ +▓▓▓▓▓▓▓▓▓ ▓▓ +▓▓ ▓▓ traperto GmbH +▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓ -▓▓▓▓▓▓▓▓▓ ▓▓ -``` \ No newline at end of file +▓▓▓▓▓▓▓▓▓ ▓▓ +```