├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── benches ├── application │ ├── x-7z-compressed │ └── zip ├── from_u8.rs ├── image │ ├── gif │ └── png ├── match_u8.rs └── text │ └── plain ├── magic_db ├── COPYING ├── Cargo.toml ├── README.md └── src │ ├── aliases │ ├── lib.rs │ ├── magic │ └── subclasses ├── src ├── basetype │ ├── check.rs │ ├── init.rs │ └── mod.rs ├── fdo_magic │ ├── builtin │ │ ├── check.rs │ │ ├── init.rs │ │ ├── mod.rs │ │ └── runtime.rs │ ├── check.rs │ ├── mod.rs │ └── ruleset.rs └── lib.rs └── tests ├── application ├── x-7z-compressed ├── x-tar └── zip ├── audio ├── flac ├── mpeg ├── ogg ├── opus └── wav ├── from_filepath.rs ├── from_u8.rs ├── image ├── bmp ├── gif ├── heic ├── png ├── tiff ├── x-pcx ├── x-portable-bitmap ├── x-tga └── xbm ├── match_u8.rs └── text ├── html └── plain /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | graph.dot 3 | graph.svg 4 | 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # tree_magic_mini 3.0.0 2 | 3 | * Split GPL-licensed files into a separate optional dependency. The main crate 4 | is now MIT-licensed, and searches for data files installed on the system at 5 | run-time by default. 6 | 7 | If you enable the `with-gpl-data` feature, then the data files will be 8 | hard-coded into the library at compile time. Programs that use this feature 9 | must be distributed according to the terms of the GNU GPL 2.0 or later. 10 | 11 | # tree_magic_mini 2.0.0 12 | 13 | * Change license to GPL-2.0-or-later for compatibility with upstream 14 | xdg-shared-mime-info license. 15 | 16 | # tree_magic_mini 1.0.1 17 | 18 | * Update to nom 6. 19 | 20 | # tree_magic_mini 1.0.0 21 | 22 | * Forked and changed name to `tree_magic_mini` 23 | * Updated dependencies. 24 | * Reduced copying and memory allocation, for a slight increase in speed and 25 | decrease in memory use. 26 | * Reduced API surface. Some previously public APIs are now internal. 27 | * Removed the optional `cli` feature and `tmagic` binary. 28 | 29 | # 0.2.3 30 | 31 | Upgraded package versions to latest (except nom, which is currently stuck at 32 | 3.x) and fixed the paths in the doc tests 33 | 34 | # 0.2.2 35 | 36 | Yanked due to accidental breaking API change 37 | 38 | # 0.2.1 39 | 40 | Incorporated fix by Bram Sanders to prevent panic on non-existent file. 41 | 42 | # 0.2.0 43 | 44 | Major changes, front-end and back. 45 | 46 | - Added `is_alias` function 47 | - `from_*` functions excluding `from_*_node` now return MIME, not Option 48 | - New feature flag: `staticmime`. Changes type of MIME from String to &'static str 49 | - Bundled magic file, so it works on Windows as well. 50 | - Split `fdo_magic` checker into `fdo_magic::sys` and `fdo_magic::builtin` 51 | - `len` argument removed from `*_u8` functions 52 | - Tests and benchmarks added. 53 | - Fixed horribly broken logic in `fdo_magic` checker 54 | - Checks the most common types before obscure types 55 | - Changed hasher to `fnv`. 56 | - Added support for handling aliases in input 57 | - `tmagic` command has more features 58 | - Major speed improvements 59 | 60 | # 0.1.1 61 | 62 | - *Changed public interface*: Added `from_u8` export function 63 | - *Changed public interface*: Changed len argument for `u8` functions from `u32` to `usize` 64 | - Minor speed improvements in `fdo_magic` checker 65 | 66 | # 0.1.0 67 | 68 | Initial release 69 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "bencher" 7 | version = "0.1.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "7dfdb4953a096c551ce9ace855a604d702e6e62d77fac690575ae347571717f5" 10 | 11 | [[package]] 12 | name = "equivalent" 13 | version = "1.0.1" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 16 | 17 | [[package]] 18 | name = "fixedbitset" 19 | version = "0.4.2" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 22 | 23 | [[package]] 24 | name = "fnv" 25 | version = "1.0.7" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 28 | 29 | [[package]] 30 | name = "hashbrown" 31 | version = "0.15.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" 34 | 35 | [[package]] 36 | name = "indexmap" 37 | version = "2.6.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" 40 | dependencies = [ 41 | "equivalent", 42 | "hashbrown", 43 | ] 44 | 45 | [[package]] 46 | name = "memchr" 47 | version = "2.7.4" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 50 | 51 | [[package]] 52 | name = "minimal-lexical" 53 | version = "0.2.1" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 56 | 57 | [[package]] 58 | name = "nom" 59 | version = "7.1.3" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 62 | dependencies = [ 63 | "memchr", 64 | "minimal-lexical", 65 | ] 66 | 67 | [[package]] 68 | name = "once_cell" 69 | version = "1.20.2" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 72 | 73 | [[package]] 74 | name = "petgraph" 75 | version = "0.6.5" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" 78 | dependencies = [ 79 | "fixedbitset", 80 | "indexmap", 81 | ] 82 | 83 | [[package]] 84 | name = "tree_magic_db" 85 | version = "3.0.1" 86 | 87 | [[package]] 88 | name = "tree_magic_mini" 89 | version = "3.1.6" 90 | dependencies = [ 91 | "bencher", 92 | "fnv", 93 | "memchr", 94 | "nom", 95 | "once_cell", 96 | "petgraph", 97 | "tree_magic_db", 98 | ] 99 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree_magic_mini" 3 | version = "3.1.6" 4 | authors = [ 5 | "Matt Brubeck ", 6 | "Allison Hancock ", 7 | ] 8 | description = "Determines the MIME type of a file by traversing a filetype tree." 9 | repository = "https://github.com/mbrubeck/tree_magic/" 10 | documentation = "https://docs.rs/tree_magic_mini/" 11 | readme = "README.md" 12 | categories = ["parser-implementations", "filesystem"] 13 | keywords = ["mime", "filesystem", "media-types"] 14 | license = "MIT" 15 | exclude = ["tests/*", "benches/*/"] 16 | edition = "2021" 17 | 18 | [dependencies] 19 | petgraph = "0.6.0" 20 | nom = "7.0" 21 | fnv = "1.0" 22 | memchr = "2.0" 23 | once_cell = "1.0" 24 | tree_magic_db = { version = "3.0", path = "./magic_db" , optional = true } 25 | 26 | [features] 27 | with-gpl-data = ["dep:tree_magic_db"] 28 | 29 | [dev-dependencies] 30 | bencher = "0.1.0" 31 | 32 | [workspace] 33 | members = ["magic_db"] 34 | 35 | [[bench]] 36 | name = "from_u8" 37 | harness = false 38 | 39 | [[bench]] 40 | name = "match_u8" 41 | harness = false 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Aaron Hancock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree_magic_mini 2 | 3 | `tree_magic_mini` is a Rust crate that determines the MIME type a given file 4 | or byte stream. 5 | 6 | Read the documentation at https://docs.rs/tree_magic_mini/ 7 | 8 | This is a fork of the [tree_magic](https://crates.io/crates/tree_magic) 9 | crate by Allison Hancock. It includes the following changes: 10 | 11 | * Updated dependencies. 12 | * Reduced copying and memory allocation, for a slight increase in speed and 13 | decrease in memory use. 14 | * Reduced API surface. Some previously public APIs are now internal. 15 | * Removed the optional `cli` feature and `tmagic` binary. 16 | * Split GPL-licensed data files into a separate optional crate. 17 | 18 | These changes were made both to make the library more efficient, and to 19 | simplify the effort to maintain and optimize of this fork. I would like to 20 | eventually merge these changes back to the original `tree_magic` crate, and/or 21 | restore some of the removed features if there is demand for that. 22 | 23 | ## Licensing and the MIME database 24 | 25 | By default, `tree_magic_mini` will attempt to load the shared MIME info 26 | database from the standard locations at runtime. 27 | 28 | If you won't have the database files available, or would like to include them 29 | in your binary for simplicity, you can optionally embed the database 30 | information if you enable the `tree_magic_db` feature. 31 | 32 | **As the magic database files themselves are licensed under the GPL, you must 33 | make sure your project uses a compatible license if you enable this behaviour.** 34 | 35 | --- 36 | 37 | Continue reading for the original `tree_magic` documentation. 38 | 39 | ## About tree_magic 40 | 41 | Unlike the typical approach that libmagic and file(1) uses, this loads all the file types in a tree based on subclasses. (EX: `application/vnd.openxmlformats-officedocument.wordprocessingml.document` (MS Office 2007) subclasses `application/zip` which subclasses `application/octet-stream`) Then, instead of checking the file against *every* file type, it can traverse down the tree and only check the file types that make sense to check. (After all, the fastest check is the check that never gets run.) 42 | 43 | This library also provides the ability to check if a file is a certain type without going through the process of checking it against every file type. 44 | 45 | ## Performance 46 | 47 | This is fast. FAST. 48 | 49 | This is a test of my Downloads folder (sorry, can't find a good publicly available set of random files) on OpenSUSE Tumbleweed. `tmagic` was compiled with `cargo build --release`, and `file` came from the OpenSUSE repos. This is a warm run, which means I've ran both programs through a few times. System is a dual-core Intel Core i7 640M, and results were measured with `time`. 50 | 51 | Program | real | user | sys 52 | --------|------|------|----- 53 | tmagic 0.2.0 | 0m0.063s | 0m0.052s | 0m0.004s 54 | file-5.30 --mime-type | 0m0.924s | 0.800s | 0.116s 55 | 56 | There's a couple things that lead to this. Mainly: 57 | 58 | - Less types to parse due to graph approach. 59 | 60 | - First 4K of file is loaded then passed to all parsers, instead of constantly reloading from disk. (When doing that, the time was more around ~0.130s.) 61 | 62 | - The most common types (image/png, image/jpeg, application/zip, etc.) are checked before the exotic ones. 63 | 64 | - Everything that can be lazily initialized is. 65 | 66 | Nightly users can also run `cargo bench` for some benchmarks. For tree_magic 0.2.0 on the same hardware: 67 | 68 | test from_u8::application_zip ... bench: 17,086 ns/iter (+/- 845) 69 | test from_u8::image_gif ... bench: 5,027 ns/iter (+/- 520) 70 | test from_u8::image_png ... bench: 4,421 ns/iter (+/- 1,795) 71 | test from_u8::text_plain ... bench: 112,578 ns/iter (+/- 11,778) 72 | test match_u8::application_zip ... bench: 222 ns/iter (+/- 144) 73 | test match_u8::image_gif ... bench: 140 ns/iter (+/- 14) 74 | test match_u8::image_png ... bench: 139 ns/iter (+/- 18) 75 | test match_u8::text_plain ... bench: 44 ns/iter (+/- 3) 76 | 77 | However, it should be noted that the FreeDesktop.org magic files less filetypes than the magic files used by libmagic. (On my system tree_magic supports 400 types, while `/usr/share/misc/magic` contains 855 `!:mime` tags.) It is, however, significantly easier to parse, as it only covers magic numbers and not attributes or anything like that. See the TODO section for plans to fix this. 78 | 79 | ## Compatibility 80 | 81 | This has been tested using Rust Stable and Nightly on Windows 7 and OpenSUSE Tumbleweed Linux. 82 | 83 | All mime information and relation information is loaded from the Shared MIME-info Database as described at https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html. If you beleive that this is not present on your system, turn off the `sys_fdo_magic` feature flag. 84 | 85 | This provides the most common file types, but it's still missing some important ones, like LibreOffice or MS Office 2007+ support or ISO files. Expect this to improve, especially as the `zip` checker is added. 86 | 87 | ### Architecture 88 | 89 | `tree_magic` is split up into different "checker" modules. Each checker handles a certain set of filetypes, and only those. For instance, the `basetype` checker handles the `inode/*` and `text/plain` types, while the `fdo_magic` checker handles anything with a magic number. Th idea here is that instead of following the `libmagic` route of having one magic descriptor format that fits every file, we can specialize and choose the checker that suits the file format best. 90 | 91 | During library initialization, each checker is queried for the types is supports and the parent->child relations between them. During this time, the checkers can load any rules, schemas, etc. into memory. A big philosophy here is that **time during the checking phase is many times more valuable than during the init phase**. The library only gets initialized once, and the library can check thousands of files during a program's lifetime. 92 | 93 | From the list of file types and relations, a directed graph is built, and each node is added to a hash map. The library user can use these directly to find parents, children, etc. of a given MIME if needed. 94 | 95 | When a file needs to be checked against a certain MIME (match_*), each checker is queried to see if it supports that type, and if so, it runs the checker. If the checker returns true, it must be that type. 96 | 97 | When a file needs it's MIME type found (from_*), the library starts at the `all/all` node of the type graph (or whichever node the user specifies) and walks down the tree. If a match is found, it continues searching down that branch. If no match is found, it retrieves the deepest MIME type found. 98 | 99 | ## TODO 100 | 101 | ### Improve fdo-magic checker 102 | 103 | Right now the `fdo-magic` checker does not handle endianess. It also does not handle magic files stored in the user's home directory. 104 | 105 | ### Additional checkers 106 | 107 | It is planned to have custom file checking functions for many types. Here's some ideas: 108 | 109 | - `zip`: Everything that subclasses `application/zip` can be determined further by peeking at the zip's directory listing. 110 | 111 | - `grep`: Text files such as program scripts and configuration files could be parsed with a regex (or whatever works best). 112 | 113 | - `json`, `toml`, `xml`, etc: Check the given file against a schema and return true if it matches. (By this point there should be few enough potential matches that it should be okay to load the entire file) 114 | 115 | - (specialized parsers): Binary (or text) files without any sort of magic can be checked for compliance against a quick and dirty `nom` parser instead of the weird heuristics used by libmagic. 116 | 117 | To add additional checker types, add a new module exporting: 118 | 119 | - `init::get_supported() -> Vec<(String)>` 120 | 121 | - `init::get_subclasses() -> Vec` 122 | 123 | - `test::from_u8(&[u8], &str) -> bool` 124 | 125 | - `test::from_filpath(&str, &str) -> Result` 126 | 127 | and then add references to those functions into the CHECKERS lazy_static! in `lib.rs`. The bottommost entries get searched first. 128 | 129 | ### Caching 130 | 131 | Going forward, it is essential for a checker (like `basetype`'s metadata, or that json/toml/xml example) to be able to cache an in-memory representation of the file, so it doesn't have to get re-loaded and re-parsed for every new type. With the current architecture, this is rather difficult to implement. 132 | 133 | ### Multiple file types 134 | 135 | There are some weird files out there ( [Polyglot quines](https://en.wikipedia.org/wiki/Polyglot_(computing)) come to mind. ) that are multiple file types. This might be worth handling for security reasons. (It's not a huge priority, though.) 136 | 137 | ### Parallel processing 138 | 139 | Right now this is single-threaded. This is an embarasingly parallel task (multiple files, multiple types, multiple rules for each type...), so there should be a great speed benefit. 140 | 141 | ## TO NOT DO 142 | 143 | ### File attributes 144 | 145 | `libmagic` and `file`, by default, print descriptive strings detailing the file type and, for things like JPEG images or ELF files, a whole bunch of metadata. This is not something `tree_magic` will ever support, as it is entirely unnecessary. Support for attributes would best be handled in a seperate crate that, given a MIME, can extract metadata in a predictable, machine readable format. 146 | -------------------------------------------------------------------------------- /benches/application/x-7z-compressed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/benches/application/x-7z-compressed -------------------------------------------------------------------------------- /benches/application/zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/benches/application/zip -------------------------------------------------------------------------------- /benches/from_u8.rs: -------------------------------------------------------------------------------- 1 | use tree_magic_mini as tree_magic; 2 | 3 | #[macro_use] 4 | extern crate bencher; 5 | use bencher::Bencher; 6 | 7 | ///Image tests 8 | fn image_gif(b: &mut Bencher) { 9 | b.iter(|| tree_magic::from_u8(include_bytes!("image/gif"))); 10 | } 11 | fn image_png(b: &mut Bencher) { 12 | b.iter(|| tree_magic::from_u8(include_bytes!("image/png"))); 13 | } 14 | 15 | /// Archive tests 16 | fn application_zip(b: &mut Bencher) { 17 | b.iter(|| tree_magic::from_u8(include_bytes!("application/zip"))); 18 | } 19 | 20 | /// Text tests 21 | fn text_plain(b: &mut Bencher) { 22 | b.iter(|| tree_magic::from_u8(include_bytes!("text/plain"))); 23 | } 24 | 25 | benchmark_group!(benches, image_gif, image_png, application_zip, text_plain); 26 | benchmark_main!(benches); 27 | -------------------------------------------------------------------------------- /benches/image/gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/benches/image/gif -------------------------------------------------------------------------------- /benches/image/png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/benches/image/png -------------------------------------------------------------------------------- /benches/match_u8.rs: -------------------------------------------------------------------------------- 1 | use tree_magic_mini as tree_magic; 2 | 3 | #[macro_use] 4 | extern crate bencher; 5 | use bencher::Bencher; 6 | 7 | ///Image benchmarks 8 | fn image_gif(b: &mut Bencher) { 9 | b.iter(|| tree_magic::match_u8("image/gif", include_bytes!("image/gif"))); 10 | } 11 | fn image_png(b: &mut Bencher) { 12 | b.iter(|| tree_magic::match_u8("image/png", include_bytes!("image/png"))); 13 | } 14 | 15 | /// Archive tests 16 | fn application_zip(b: &mut Bencher) { 17 | b.iter(|| tree_magic::match_u8("application/zip", include_bytes!("application/zip"))); 18 | } 19 | 20 | /// Text tests 21 | fn text_plain(b: &mut Bencher) { 22 | b.iter(|| tree_magic::match_u8("text/plain", include_bytes!("text/plain"))); 23 | } 24 | 25 | benchmark_group!(benches, image_gif, image_png, application_zip, text_plain); 26 | benchmark_main!(benches); 27 | -------------------------------------------------------------------------------- /benches/text/plain: -------------------------------------------------------------------------------- 1 | This is just standard text. 2 | -------------------------------------------------------------------------------- /magic_db/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /magic_db/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree_magic_db" 3 | version = "3.0.1" 4 | authors = ["Richard Bradfield "] 5 | description = "Packages the FreeDesktop.org shared MIME database for optional use with tree_magic_mini" 6 | license = "GPL-2.0-or-later" 7 | edition = "2021" 8 | repository = "https://github.com/mbrubeck/tree_magic/" 9 | -------------------------------------------------------------------------------- /magic_db/README.md: -------------------------------------------------------------------------------- 1 | # Magic DB 2 | 3 | This subcrate contains the magic definitions copied from the FreeDesktop.org 4 | shared MIME info database. 5 | 6 | These files are distributed under the GPL-2.0 or later, as such if you include 7 | them in your project, it must be licensed in a compatible manner. 8 | 9 | # References 10 | 11 | - [xdg-shared-mime-info Repository](https://gitlab.freedesktop.org/xdg/shared-mime-info) 12 | - [FreeDesktop shared-mime-info Spec](https://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec/) 13 | 14 | # Licence 15 | 16 | The contents of this crate are licenced under the GNU General Public License, 17 | version 2.0 or later, at your option: 18 | 19 | * GNU GPL, Version 2.0 ([COPYING](COPYING) or https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt) 20 | -------------------------------------------------------------------------------- /magic_db/src/aliases: -------------------------------------------------------------------------------- 1 | application/acrobat application/pdf 2 | application/bat application/x-bat 3 | application/bzip2 application/x-bzip2 4 | application/cdr application/vnd.corel-draw 5 | application/coreldraw application/vnd.corel-draw 6 | application/dbase application/vnd.dbf 7 | application/dbf application/vnd.dbf 8 | application/docbook+xml application/x-docbook+xml 9 | application/emf image/emf 10 | application/font-woff font/woff 11 | application/futuresplash application/vnd.adobe.flash.movie 12 | application/gpx application/gpx+xml 13 | application/ico image/vnd.microsoft.icon 14 | application/ics text/calendar 15 | application/java application/x-java 16 | application/java-byte-code application/x-java 17 | application/java-vm application/x-java 18 | application/javascript text/javascript 19 | application/lotus123 application/vnd.lotus-1-2-3 20 | application/m3u audio/x-mpegurl 21 | application/mdb application/vnd.ms-access 22 | application/ms-tnef application/vnd.ms-tnef 23 | application/msaccess application/vnd.ms-access 24 | application/msexcel application/vnd.ms-excel 25 | application/mspowerpoint application/vnd.ms-powerpoint 26 | application/nappdf application/pdf 27 | application/pcap application/vnd.tcpdump.pcap 28 | application/pgp application/pgp-encrypted 29 | application/photoshop image/vnd.adobe.photoshop 30 | application/pkcs12 application/x-pkcs12 31 | application/pls audio/x-scpls 32 | application/powerpoint application/vnd.ms-powerpoint 33 | application/smil application/smil+xml 34 | application/stuffit application/x-stuffit 35 | application/tga image/x-tga 36 | application/vnd.adobe.illustrator application/illustrator 37 | application/vnd.geo+json application/geo+json 38 | application/vnd.haansoft-hwp application/x-hwp 39 | application/vnd.haansoft-hwt application/x-hwt 40 | application/vnd.ms-3mfdocument model/3mf 41 | application/vnd.ms-word application/msword 42 | application/vnd.msaccess application/vnd.ms-access 43 | application/vnd.oasis.docbook+xml application/x-docbook+xml 44 | application/vnd.rn-realmedia-vbr application/vnd.rn-realmedia 45 | application/vnd.sdp application/sdp 46 | application/vnd.stardivision.writer-global application/vnd.stardivision.writer 47 | application/vnd.sun.xml.base application/vnd.oasis.opendocument.database 48 | application/vnd.truedoc application/font-tdpfr 49 | application/vnd.xdgapp application/vnd.flatpak 50 | application/vnd.youtube.yt video/vnd.youtube.yt 51 | application/wk1 application/vnd.lotus-1-2-3 52 | application/wmf image/wmf 53 | application/wordperfect application/vnd.wordperfect 54 | application/wwf application/x-wwf 55 | application/x-123 application/vnd.lotus-1-2-3 56 | application/x-annodex application/annodex 57 | application/x-bzip application/x-bzip2 58 | application/x-bzip-compressed-tar application/x-bzip2-compressed-tar 59 | application/x-cbr application/vnd.comicbook-rar 60 | application/x-cbz application/vnd.comicbook+zip 61 | application/x-cd-image application/vnd.efi.iso 62 | application/x-cdr application/vnd.corel-draw 63 | application/x-chess-pgn application/vnd.chess-pgn 64 | application/x-chm application/vnd.ms-htmlhelp 65 | application/x-coreldraw application/vnd.corel-draw 66 | application/x-dbase application/vnd.dbf 67 | application/x-dbf application/vnd.dbf 68 | application/x-deb application/vnd.debian.binary-package 69 | application/x-debian-package application/vnd.debian.binary-package 70 | application/x-emf image/emf 71 | application/x-fd-file application/x-raw-floppy-disk-image 72 | application/x-fictionbook application/x-fictionbook+xml 73 | application/x-flash-video video/x-flv 74 | application/x-font-otf font/otf 75 | application/x-font-ttf font/ttf 76 | application/x-frame application/vnd.framemaker 77 | application/x-gamecube-iso-image application/x-gamecube-rom 78 | application/x-gedcom text/vnd.familysearch.gedcom 79 | application/x-gerber application/vnd.gerber 80 | application/x-gettext text/x-gettext-translation 81 | application/x-gnome-app-info application/x-desktop 82 | application/x-gpx application/gpx+xml 83 | application/x-gpx+xml application/gpx+xml 84 | application/x-gtar application/x-tar 85 | application/x-gzip application/gzip 86 | application/x-hfe-file application/x-hfe-floppy-image 87 | application/x-iso9660-image application/vnd.efi.iso 88 | application/x-iwork-keynote-sffkey application/vnd.apple.keynote 89 | application/x-iwork-numbers-sffnumbers application/vnd.apple.numbers 90 | application/x-iwork-pages-sffpages application/vnd.apple.pages 91 | application/x-jar application/java-archive 92 | application/x-java-archive application/java-archive 93 | application/x-java-class application/x-java 94 | application/x-java-vm application/x-java 95 | application/x-javascript text/javascript 96 | application/x-kexiproject-sqlite application/x-kexiproject-sqlite3 97 | application/x-linguist text/vnd.trolltech.linguist 98 | application/x-lotus123 application/vnd.lotus-1-2-3 99 | application/x-lzh-compressed application/x-lha 100 | application/x-mathematica application/mathematica 101 | application/x-mdb application/vnd.ms-access 102 | application/x-mobi8-ebook application/vnd.amazon.mobi8-ebook 103 | application/x-mobipocket-subscription-magazine application/x-mobipocket-subscription 104 | application/x-ms-asx audio/x-ms-asx 105 | application/x-ms-dos-executable application/x-msdownload 106 | application/x-msaccess application/vnd.ms-access 107 | application/x-msexcel application/vnd.ms-excel 108 | application/x-msmetafile image/wmf 109 | application/x-mspowerpoint application/vnd.ms-powerpoint 110 | application/x-msword application/msword 111 | application/x-netscape-bookmarks application/x-mozilla-bookmarks 112 | application/x-ogg application/ogg 113 | application/x-palm-database application/vnd.palm 114 | application/x-pcap application/vnd.tcpdump.pcap 115 | application/x-pdf application/pdf 116 | application/x-photoshop image/vnd.adobe.photoshop 117 | application/x-pkcs12 application/pkcs12 118 | application/x-pkcs7-certificates application/pkcs7-mime 119 | application/x-quicktimeplayer application/x-quicktime-media-link 120 | application/x-rar application/vnd.rar 121 | application/x-rar-compressed application/vnd.rar 122 | application/x-raw-disk-image application/vnd.efi.img 123 | application/x-redhat-package-manager application/x-rpm 124 | application/x-reject text/x-reject 125 | application/x-rnc application/relax-ng-compact-syntax 126 | application/x-sap-file application/x-thomson-sap-image 127 | application/x-sdp application/sdp 128 | application/x-shockwave-flash application/vnd.adobe.flash.movie 129 | application/x-sit application/x-stuffit 130 | application/x-sitx application/x-stuffitx 131 | application/x-smaf application/vnd.smaf 132 | application/x-snes-rom application/vnd.nintendo.snes.rom 133 | application/x-spss-savefile application/x-spss-sav 134 | application/x-sqlite3 application/vnd.sqlite3 135 | application/x-srt application/x-subrip 136 | application/x-targa image/x-tga 137 | application/x-tex text/x-tex 138 | application/x-tga image/x-tga 139 | application/x-trig application/trig 140 | application/x-troff text/troff 141 | application/x-virtualbox-ova application/ovf 142 | application/x-virtualbox-vdi application/x-vdi-disk 143 | application/x-virtualbox-vhd application/x-vhd-disk 144 | application/x-virtualbox-vhdx application/x-vhdx-disk 145 | application/x-virtualbox-vmdk application/x-vmdk-disk 146 | application/x-vnd.kde.kexi application/x-kexiproject-sqlite3 147 | application/x-wbfs application/x-wii-rom 148 | application/x-wia application/x-wii-rom 149 | application/x-wii-iso-image application/x-wii-rom 150 | application/x-win-lnk application/x-ms-shortcut 151 | application/x-wmf image/wmf 152 | application/x-wordperfect application/vnd.wordperfect 153 | application/x-x509-ca-cert application/pkix-cert 154 | application/x-x509-user-cert application/pkix-cert 155 | application/x-xliff application/xliff+xml 156 | application/x-xspf+xml application/xspf+xml 157 | application/x-yaml application/yaml 158 | application/x-zip application/zip 159 | application/x-zip-compressed application/zip 160 | application/xps application/vnd.ms-xpsdocument 161 | audio/3gpp video/3gpp 162 | audio/3gpp-encrypted video/3gpp 163 | audio/3gpp2 video/3gpp2 164 | audio/amr-encrypted audio/AMR 165 | audio/amr-wb-encrypted audio/AMR-WB 166 | audio/dff audio/x-dff 167 | audio/dsd audio/x-dsf 168 | audio/dsf audio/x-dsf 169 | audio/iMelody text/x-iMelody 170 | audio/m3u audio/x-mpegurl 171 | audio/m4a audio/mp4 172 | audio/mp3 audio/mpeg 173 | audio/mpegurl audio/x-mpegurl 174 | audio/scpls audio/x-scpls 175 | audio/tta audio/x-tta 176 | audio/vnd.audible audio/x-pn-audibleaudio 177 | audio/vnd.m-realaudio audio/vnd.rn-realaudio 178 | audio/vnd.nokia.mobile-xmf audio/mobile-xmf 179 | audio/vorbis audio/x-vorbis+ogg 180 | audio/wav audio/vnd.wave 181 | audio/wma audio/x-ms-wma 182 | audio/x-aac audio/aac 183 | audio/x-aiffc audio/x-aifc 184 | audio/x-annodex audio/annodex 185 | audio/x-dsd audio/x-dsf 186 | audio/x-dts audio/vnd.dts 187 | audio/x-dtshd audio/vnd.dts.hd 188 | audio/x-flac audio/flac 189 | audio/x-iMelody text/x-iMelody 190 | audio/x-m3u audio/x-mpegurl 191 | audio/x-m4a audio/mp4 192 | audio/x-midi audio/midi 193 | audio/x-mp2 audio/mp2 194 | audio/x-mp3 audio/mpeg 195 | audio/x-mp3-playlist audio/x-mpegurl 196 | audio/x-mpeg audio/mpeg 197 | audio/x-mpg audio/mpeg 198 | audio/x-ogg audio/ogg 199 | audio/x-oggflac audio/x-flac+ogg 200 | audio/x-pn-realaudio audio/vnd.rn-realaudio 201 | audio/x-rn-3gpp-amr video/3gpp 202 | audio/x-rn-3gpp-amr-encrypted video/3gpp 203 | audio/x-rn-3gpp-amr-wb video/3gpp 204 | audio/x-rn-3gpp-amr-wb-encrypted video/3gpp 205 | audio/x-shorten application/x-shorten 206 | audio/x-vorbis audio/x-vorbis+ogg 207 | audio/x-wav audio/vnd.wave 208 | audio/xmf audio/x-xmf 209 | flv-application/octet-stream video/x-flv 210 | image/avif-sequence image/avif 211 | image/cdr application/vnd.corel-draw 212 | image/fax-g3 image/g3fax 213 | image/fits application/fits 214 | image/heic image/heif 215 | image/heic-sequence image/heif 216 | image/heif-sequence image/heif 217 | image/ico image/vnd.microsoft.icon 218 | image/icon image/vnd.microsoft.icon 219 | image/jpeg2000 image/jp2 220 | image/jpeg2000-image image/jp2 221 | image/pdf application/pdf 222 | image/photoshop image/vnd.adobe.photoshop 223 | image/pjpeg image/jpeg 224 | image/psd image/vnd.adobe.photoshop 225 | image/targa image/x-tga 226 | image/tga image/x-tga 227 | image/vnd.mozilla.apng image/apng 228 | image/vnd.ms-photo image/jxr 229 | image/x-MS-bmp image/bmp 230 | image/x-bmp image/bmp 231 | image/x-cdr application/vnd.corel-draw 232 | image/x-djvu image/vnd.djvu 233 | image/x-emf image/emf 234 | image/x-fits application/fits 235 | image/x-icb image/x-tga 236 | image/x-ico image/vnd.microsoft.icon 237 | image/x-icon image/vnd.microsoft.icon 238 | image/x-iff image/x-ilbm 239 | image/x-jpeg2000-image image/jp2 240 | image/x-panasonic-raw image/x-panasonic-rw 241 | image/x-panasonic-raw2 image/x-panasonic-rw2 242 | image/x-pcx image/vnd.zbrush.pcx 243 | image/x-photoshop image/vnd.adobe.photoshop 244 | image/x-psd image/vnd.adobe.photoshop 245 | image/x-targa image/x-tga 246 | image/x-win-metafile image/wmf 247 | image/x-wmf image/wmf 248 | image/x-xpm image/x-xpixmap 249 | image/x.djvu image/vnd.djvu 250 | model/x.stl-ascii model/stl 251 | model/x.stl-binary model/stl 252 | text/crystal text/x-crystal 253 | text/directory text/vcard 254 | text/ecmascript application/ecmascript 255 | text/gedcom text/vnd.familysearch.gedcom 256 | text/google-video-pointer text/x-google-video-pointer 257 | text/ico image/vnd.microsoft.icon 258 | text/jscript text/javascript 259 | text/mathml application/mathml+xml 260 | text/rdf application/rdf+xml 261 | text/rss application/rss+xml 262 | text/rtf application/rtf 263 | text/vbs text/vbscript 264 | text/vnd.qt.linguist text/vnd.trolltech.linguist 265 | text/x-c text/x-csrc 266 | text/x-comma-separated-values text/csv 267 | text/x-csv text/csv 268 | text/x-dart application/vnd.dart 269 | text/x-diff text/x-patch 270 | text/x-dtd application/xml-dtd 271 | text/x-fish application/x-fishscript 272 | text/x-lyx application/x-lyx 273 | text/x-markdown text/markdown 274 | text/x-nu application/x-nuscript 275 | text/x-octave text/x-matlab 276 | text/x-opml text/x-opml+xml 277 | text/x-perl application/x-perl 278 | text/x-po text/x-gettext-translation 279 | text/x-pot text/x-gettext-translation-template 280 | text/x-sh application/x-shellscript 281 | text/x-sql application/sql 282 | text/x-tcl text/tcl 283 | text/x-troff text/troff 284 | text/x-vcalendar text/calendar 285 | text/x-vcard text/vcard 286 | text/x-yaml application/yaml 287 | text/xml application/xml 288 | text/xml-external-parsed-entity application/xml-external-parsed-entity 289 | text/yaml application/yaml 290 | video/3gp video/3gpp 291 | video/3gpp-encrypted video/3gpp 292 | video/avi video/vnd.avi 293 | video/divx video/vnd.avi 294 | video/fli video/x-flic 295 | video/flv video/x-flv 296 | video/mp4v-es video/mp4 297 | video/mpeg-system video/mpeg 298 | video/msvideo video/vnd.avi 299 | video/vivo video/vnd.vivo 300 | video/vnd.divx video/vnd.avi 301 | video/x-annodex video/annodex 302 | video/x-avi video/vnd.avi 303 | video/x-fli video/x-flic 304 | video/x-m4v video/mp4 305 | video/x-mpeg video/mpeg 306 | video/x-mpeg-system video/mpeg 307 | video/x-mpeg2 video/mpeg 308 | video/x-mpegurl video/vnd.mpegurl 309 | video/x-ms-asf application/vnd.ms-asf 310 | video/x-ms-asf-plugin application/vnd.ms-asf 311 | video/x-ms-wax audio/x-ms-asx 312 | video/x-ms-wm application/vnd.ms-asf 313 | video/x-ms-wmx audio/x-ms-asx 314 | video/x-ms-wvx audio/x-ms-asx 315 | video/x-msvideo video/vnd.avi 316 | video/x-ogg video/ogg 317 | video/x-ogm video/x-ogm+ogg 318 | video/x-real-video video/vnd.rn-realvideo 319 | video/x-theora video/x-theora+ogg 320 | x-directory/normal inode/directory 321 | zz-application/zz-winassoc-123 application/vnd.lotus-1-2-3 322 | zz-application/zz-winassoc-cab application/vnd.ms-cab-compressed 323 | zz-application/zz-winassoc-cdr application/vnd.corel-draw 324 | zz-application/zz-winassoc-doc application/msword 325 | zz-application/zz-winassoc-hlp application/winhlp 326 | zz-application/zz-winassoc-mdb application/vnd.ms-access 327 | zz-application/zz-winassoc-uu text/x-uuencode 328 | zz-application/zz-winassoc-xls application/vnd.ms-excel 329 | -------------------------------------------------------------------------------- /magic_db/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Packaging crate for the FreeDesktop.org shared MIME info database 2 | 3 | // This program is free software; you can redistribute it and/or 4 | // modify it under the terms of the GNU General Public License 5 | // as published by the Free Software Foundation; either version 2 6 | // of the License, or (at your option) any later version. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | /// Returns a static reference to the MIME database 'aliases' 14 | pub fn aliases() -> &'static str { 15 | include_str!("aliases") 16 | } 17 | 18 | /// Returns a static reference to the MIME database 'subclasses' 19 | pub fn subclasses() -> &'static str { 20 | include_str!("subclasses") 21 | } 22 | 23 | /// Returns a static reference to the MIME database 'magic' data 24 | pub fn magic() -> &'static [u8] { 25 | include_bytes!("magic") 26 | } 27 | -------------------------------------------------------------------------------- /magic_db/src/magic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/magic_db/src/magic -------------------------------------------------------------------------------- /magic_db/src/subclasses: -------------------------------------------------------------------------------- 1 | model/vrml text/plain 2 | text/x-kaitai-struct application/yaml 3 | application/msix application/zip 4 | application/vnd.ms-officetheme application/zip 5 | text/x-gradle text/x-groovy 6 | application/x-lyx text/plain 7 | application/vnd.oasis.opendocument.spreadsheet-template application/zip 8 | application/xhtml+xml application/xml 9 | application/vnd.openxmlformats-officedocument.wordprocessingml.document application/zip 10 | text/x-credits text/plain 11 | application/x-raw-floppy-disk-image application/vnd.efi.img 12 | application/vnd.oasis.opendocument.text-web application/zip 13 | text/x-gettext-translation text/plain 14 | application/metalink+xml application/xml 15 | text/x-uil text/plain 16 | application/gpx+xml application/xml 17 | text/x-basic text/plain 18 | application/vnd.oasis.opendocument.chart application/zip 19 | application/vnd.sun.xml.draw.template application/zip 20 | video/annodex application/annodex 21 | application/pkcs12+pem application/x-pem-file 22 | application/x-netshow-channel application/vnd.ms-asf 23 | application/xliff+xml application/xml 24 | application/vnd.visio application/x-ole-storage 25 | application/x-modrinth-modpack+zip application/zip 26 | application/vnd.oasis.opendocument.text application/zip 27 | application/vnd.oasis.opendocument.chart-template application/zip 28 | text/vnd.wap.wml application/xml 29 | application/owl+xml application/xml 30 | application/vnd.sun.xml.writer.global application/zip 31 | application/x-nuscript application/x-executable 32 | application/x-nuscript text/plain 33 | text/x-vb text/plain 34 | application/x-kindle-application application/x-java-archive 35 | application/x-audacity-project text/xml 36 | application/vnd.ms-excel.addin.macroEnabled.12 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 37 | application/vnd.ms-excel.sheet.binary.macroEnabled.12 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 38 | application/x-wais-source text/plain 39 | image/x-sony-arw image/x-dcraw 40 | image/x-sony-arw image/tiff 41 | application/vnd.ms-visio.template.macroEnabled.main+xml application/zip 42 | image/x-portable-bitmap image/x-portable-anymap 43 | application/x-designer application/xml 44 | image/x-sony-srf image/x-dcraw 45 | image/x-sony-srf image/tiff 46 | text/x-cobol text/plain 47 | audio/x-vorbis+ogg audio/ogg 48 | application/x-magicpoint text/plain 49 | application/x-awk application/x-executable 50 | application/x-awk text/plain 51 | application/vnd.apple.pages application/zip 52 | application/x-openvpn-profile text/plain 53 | text/vnd.senx.warpscript text/plain 54 | application/x-bzip3-compressed-tar application/x-bzip3 55 | application/x-bat text/plain 56 | application/x-fictionbook+xml application/xml 57 | text/x-mrml application/xml 58 | application/x-csh application/x-shellscript 59 | application/x-csh text/plain 60 | application/java-archive application/zip 61 | text/markdown text/plain 62 | image/apng image/png 63 | application/x-tarz application/x-compress 64 | text/tab-separated-values text/plain 65 | text/x-dsl text/plain 66 | application/x-aportisdoc application/vnd.palm 67 | audio/x-opus+ogg audio/ogg 68 | application/x-apple-systemprofiler+xml application/xml 69 | text/x-patch text/plain 70 | application/x-tzo application/x-lzop 71 | application/vnd.openxmlformats-officedocument.presentationml.slide application/zip 72 | application/epub+zip application/zip 73 | text/x-xslfo application/xml 74 | application/x-ipynb+json application/json 75 | text/x-scala text/plain 76 | application/vnd.ms-powerpoint.slide.macroEnabled.12 application/vnd.openxmlformats-officedocument.presentationml.slide 77 | text/x-verilog text/plain 78 | application/msword application/x-ole-storage 79 | text/x-authors text/plain 80 | text/x-subviewer text/plain 81 | image/openraster application/zip 82 | application/vnd.oasis.opendocument.presentation-flat-xml application/xml 83 | application/vnd.oasis.opendocument.presentation-flat-xml application/xml 84 | text/x-csharp text/x-csrc 85 | application/x-cdrdao-toc text/plain 86 | application/x-wwf application/pdf 87 | audio/vnd.wave application/x-riff 88 | text/x-vhdl text/plain 89 | application/vnd.oasis.opendocument.formula application/zip 90 | application/vnd.ms-xpsdocument application/zip 91 | text/x-fortran text/plain 92 | text/html text/plain 93 | application/x-dosexec application/x-msdownload 94 | application/vnd.gerber text/plain 95 | text/x-opml+xml application/xml 96 | application/ovf application/x-tar 97 | application/x-compressed-tar application/gzip 98 | text/x-genie text/plain 99 | application/appx application/zip 100 | application/vnd.ms-powerpoint.slideshow.macroEnabled.12 application/vnd.openxmlformats-officedocument.presentationml.slideshow 101 | text/x-ldif text/plain 102 | image/x-kodak-kdc image/x-dcraw 103 | image/x-kodak-kdc image/tiff 104 | application/vnd.oasis.opendocument.formula-template application/zip 105 | text/x-blueprint text/plain 106 | text/vnd.trolltech.linguist application/xml 107 | application/x-perl application/x-executable 108 | application/x-perl text/plain 109 | video/x-ms-wmv application/vnd.ms-asf 110 | text/x-uri text/plain 111 | application/x-gzpostscript application/gzip 112 | application/x-cbt application/x-tar 113 | text/x-matlab text/plain 114 | video/x-ogm+ogg video/ogg 115 | application/xslt+xml application/xml 116 | text/x-moc text/plain 117 | text/cache-manifest text/plain 118 | text/x-uuencode text/plain 119 | application/pkcs7-mime+pem application/x-pem-file 120 | text/x-java text/x-csrc 121 | text/x-iptables text/plain 122 | message/partial text/plain 123 | application/schema+json application/json 124 | text/x-install text/plain 125 | text/x-todo-txt text/plain 126 | text/x-systemd-unit text/plain 127 | application/x-desktop text/plain 128 | text/vnd.graphviz text/plain 129 | text/xmcd text/plain 130 | application/postscript text/plain 131 | video/vnd.mpegurl text/plain 132 | application/x-windows-themepack application/vnd.ms-cab-compressed 133 | text/x-makefile text/plain 134 | application/yaml text/plain 135 | text/x-mof text/x-csrc 136 | application/x-zip-compressed-fb2 application/zip 137 | application/x-qtiplot text/plain 138 | application/vnd.ms-visio.stencil.macroEnabled.main+xml application/zip 139 | application/vnd.ms-powerpoint.template.macroEnabled.12 application/vnd.openxmlformats-officedocument.presentationml.template 140 | chemical/x-pdb text/plain 141 | text/x-crystal text/plain 142 | text/vnd.rn-realtext text/plain 143 | application/gml+xml application/xml 144 | text/richtext text/plain 145 | application/ecmascript text/javascript 146 | application/mac-binhex40 text/plain 147 | application/x-ms-ne-executable application/x-msdownload 148 | text/x-elixir text/plain 149 | image/x-canon-crw image/x-dcraw 150 | application/vnd.efi.iso application/vnd.efi.img 151 | text/vnd.familysearch.gedcom text/plain 152 | application/x-audacity-project+sqlite3 application/vdn.sqlite3 153 | application/vnd.oasis.opendocument.database application/zip 154 | text/css text/plain 155 | x-content/win32-software x-content/software 156 | text/x-nimscript text/x-nim 157 | text/x-gherkin text/plain 158 | image/x-adobe-dng image/x-dcraw 159 | image/x-adobe-dng image/tiff 160 | application/vnd.chess-pgn text/plain 161 | image/x-bzeps application/x-bzip2 162 | application/x-troff-man text/plain 163 | text/rfc822-headers text/plain 164 | text/x-scons text/x-python 165 | text/csv text/plain 166 | text/x-groovy text/x-csrc 167 | application/x-java-jnlp-file application/xml 168 | image/x-panasonic-rw image/x-dcraw 169 | audio/x-minipsf audio/x-psf 170 | audio/x-aifc application/x-iff 171 | application/vnd.openxmlformats-officedocument.spreadsheetml.template application/zip 172 | application/vnd.ms-excel application/x-ole-storage 173 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/zip 174 | application/trig text/plain 175 | text/x-maven+xml application/xml 176 | text/vbscript text/plain 177 | application/x-ufraw application/xml 178 | application/vnd.ms-excel.template.macroEnabled.12 application/vnd.openxmlformats-officedocument.spreadsheetml.template 179 | application/vnd.sun.xml.writer.template application/zip 180 | application/x-go-sgf text/plain 181 | application/sparql-results+xml application/xml 182 | text/x-ocaml text/plain 183 | audio/x-aiff application/x-iff 184 | inode/mount-point inode/directory 185 | application/x-m4 text/plain 186 | text/x-objc++src text/x-c++src 187 | text/x-objc++src text/x-objcsrc 188 | application/vnd.ms-visio.drawing.macroEnabled.main+xml application/zip 189 | message/rfc822 text/plain 190 | application/vnd.cups-ppd text/plain 191 | text/x-google-video-pointer text/plain 192 | application/relax-ng-compact-syntax text/plain 193 | image/x-pentax-pef image/x-dcraw 194 | image/x-pentax-pef image/tiff 195 | application/vnd.ms-word.template.macroEnabled.12 application/vnd.openxmlformats-officedocument.wordprocessingml.template 196 | application/x-lzip-compressed-tar application/x-lzip 197 | application/x-glade application/xml 198 | audio/x-matroska application/x-matroska 199 | text/x-troff-me text/plain 200 | application/x-docbook+xml application/xml 201 | application/mathematica text/plain 202 | image/svg+xml application/xml 203 | text/vcard text/plain 204 | application/pkcs8+pem application/x-pem-file 205 | image/x-ilbm application/x-iff 206 | video/x-mjpeg image/jpeg 207 | application/its+xml application/xml 208 | application/vnd.apple.mpegurl text/plain 209 | application/x-mswinurl text/plain 210 | image/x-gzeps application/gzip 211 | application/x-bzdvi application/x-bzip2 212 | text/x-scss text/plain 213 | application/rdf+xml application/xml 214 | application/jrd+json application/json 215 | text/troff text/plain 216 | application/pkcs10+pem application/x-pem-file 217 | application/vnd.comicbook-rar application/vnd.rar 218 | application/sql text/plain 219 | audio/x-ms-wma application/vnd.ms-asf 220 | application/vnd.android.package-archive application/java-archive 221 | application/x-pyspread-bz-spreadsheet application/x-bzip2 222 | application/x-zstd-compressed-tar application/zstd 223 | application/vnd.sun.xml.writer application/zip 224 | image/x-portable-pixmap image/x-portable-anymap 225 | text/x-emacs-lisp text/plain 226 | application/x-theme application/x-desktop 227 | application/vnd.openxmlformats-officedocument.presentationml.slideshow application/zip 228 | image/x-fuji-raf image/x-dcraw 229 | image/x-nikon-nrw image/x-dcraw 230 | image/x-nikon-nrw image/tiff 231 | application/vnd.sun.xml.impress application/zip 232 | text/x-reject text/plain 233 | text/x-bibtex text/plain 234 | application/vnd.oasis.opendocument.text-flat-xml application/xml 235 | application/vnd.oasis.opendocument.text-flat-xml application/xml 236 | application/x-subrip text/plain 237 | text/x-dcl text/plain 238 | text/x-sagemath text/x-python 239 | application/x-pem-key application/x-pem-file 240 | application/x-markaby application/x-ruby 241 | application/x-msi application/x-ole-storage 242 | text/x-troff-mm text/troff 243 | application/vnd.oasis.opendocument.graphics-flat-xml application/xml 244 | application/vnd.oasis.opendocument.graphics-flat-xml application/xml 245 | text/x-rpm-spec text/plain 246 | application/vnd.openxmlformats-officedocument.wordprocessingml.template application/zip 247 | text/x-idl text/plain 248 | application/vnd.oasis.opendocument.spreadsheet application/zip 249 | application/oxps application/zip 250 | application/x-godot-shader text/plain 251 | application/x-tiled-tmx application/xml 252 | application/json5 text/javascript 253 | application/mathml+xml application/xml 254 | text/x-rst text/plain 255 | application/x-gzdvi application/gzip 256 | audio/x-m4b audio/mp4 257 | text/x-ms-regedit text/plain 258 | text/x-mup text/plain 259 | application/x-kexiproject-sqlite2 application/x-sqlite2 260 | audio/x-flac+ogg audio/ogg 261 | application/x-gnuplot text/plain 262 | application/x-bzip2-compressed-tar application/x-bzip2 263 | application/x-kexiproject-sqlite3 application/vnd.sqlite3 264 | text/x-ocl text/plain 265 | audio/ogg application/ogg 266 | text/x-readme text/plain 267 | text/x-pascal text/plain 268 | image/svg+xml-compressed application/gzip 269 | application/x-font-type1 application/postscript 270 | application/json application/json5 271 | text/x-erlang text/plain 272 | text/x-cmake text/plain 273 | text/x-log text/plain 274 | text/x-troff-ms text/plain 275 | text/x-changelog text/plain 276 | application/vnd.openofficeorg.extension application/zip 277 | text/x-qml text/plain 278 | application/x-pagemaker application/x-ole-storage 279 | text/x-haskell text/plain 280 | text/x-typst text/plain 281 | application/vnd.google-earth.kmz application/zip 282 | image/x-sony-sr2 image/x-dcraw 283 | image/x-sony-sr2 image/tiff 284 | text/x-common-lisp text/plain 285 | image/x-canon-cr2 image/x-dcraw 286 | image/x-canon-cr2 image/tiff 287 | application/vnd.ms-word.document.macroEnabled.12 application/vnd.openxmlformats-officedocument.wordprocessingml.document 288 | text/x-twig text/plain 289 | audio/vnd.dts.hd audio/vnd.dts 290 | application/vnd.oasis.opendocument.spreadsheet-flat-xml application/xml 291 | application/vnd.oasis.opendocument.spreadsheet-flat-xml application/xml 292 | image/x-canon-cr3 image/x-dcraw 293 | application/vnd.ms-visio.template.main+xml application/zip 294 | text/vnd.wap.wmlscript text/plain 295 | application/x-pem-file text/plain 296 | application/x-dia-diagram application/xml 297 | application/x-gz-font-linux-psf application/gzip 298 | application/x-cb7 application/x-7z-compressed 299 | video/ogg application/ogg 300 | application/x-shared-library-la text/plain 301 | text/julia text/plain 302 | text/vtt text/plain 303 | application/x-cpio-compressed application/gzip 304 | application/x-mobipocket-subscription application/x-mobipocket-ebook 305 | application/vnd.sun.xml.math application/zip 306 | text/x-microdvd text/plain 307 | application/metalink4+xml application/xml 308 | application/vnd.oasis.opendocument.presentation application/zip 309 | text/org text/plain 310 | text/x-lua application/x-executable 311 | text/x-lua text/plain 312 | text/sgml text/plain 313 | application/xspf+xml application/xml 314 | application/x-lz4-compressed-tar application/x-lz4 315 | text/x-copying text/plain 316 | application/x-lzma-compressed-tar application/x-lzma 317 | application/x-nzb application/xml 318 | application/vnd.oasis.opendocument.text-master application/zip 319 | application/x-tiled-tsx application/xml 320 | application/vnd.dart text/plain 321 | application/toml text/plain 322 | text/x-eiffel text/plain 323 | application/vnd.ms-excel.sheet.macroEnabled.12 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 324 | image/x-olympus-orf image/x-dcraw 325 | text/x-iMelody text/plain 326 | application/atom+xml application/xml 327 | text/x-xmi application/xml 328 | application/vnd.coffeescript text/plain 329 | text/x-literate-haskell text/plain 330 | audio/annodex application/annodex 331 | image/x-nikon-nef image/x-dcraw 332 | image/x-nikon-nef image/tiff 333 | application/x-shellscript application/x-executable 334 | application/x-shellscript text/plain 335 | application/vnd.ms-visio.stencil.main+xml application/zip 336 | text/htmlh text/plain 337 | application/x-raw-disk-image-xz-compressed application/x-xz 338 | application/vnd.apple.numbers application/zip 339 | video/x-matroska-3d application/x-matroska 340 | application/x-msdownload application/x-executable 341 | application/xml text/plain 342 | application/vnd.oasis.opendocument.image application/zip 343 | text/x-setext text/plain 344 | text/vbscript.encode application/x-executable 345 | text/vbscript.encode text/plain 346 | application/xml-external-parsed-entity application/xml 347 | model/gltf+json application/json 348 | audio/x-m4r video/mp4 349 | image/x-sigma-x3f image/x-dcraw 350 | application/vnd.oasis.opendocument.presentation-template application/zip 351 | application/vnd.ms-works application/x-ole-storage 352 | audio/webm video/webm 353 | text/javascript application/x-executable 354 | text/javascript text/plain 355 | application/vnd.microsoft.windows.thumbnail-cache application/x-ole-storage 356 | application/msword-template application/msword 357 | application/x-godot-project text/plain 358 | text/x-mpl2 text/plain 359 | application/x-dia-shape application/xml 360 | application/rtf text/plain 361 | text/x-ooc text/x-csrc 362 | application/x-excellon text/plain 363 | application/x-mobipocket-ebook application/x-palm-database 364 | application/x-mobipocket-ebook application/vnd.palm 365 | application/vnd.amazon.mobi8-ebook application/x-mobipocket-ebook 366 | model/3mf application/zip 367 | text/x-dbus-service text/plain 368 | application/x-source-rpm application/x-rpm 369 | application/x-font-ttx application/xml 370 | text/x-c++src text/x-csrc 371 | application/vnd.appimage application/x-executable 372 | application/vnd.appimage application/vnd.squashfs 373 | application/x-profile text/plain 374 | application/vnd.snap application/vnd.squashfs 375 | application/mbox text/plain 376 | image/x-eps application/postscript 377 | application/pkix-crl+pem application/x-pem-file 378 | application/x-abiword application/xml 379 | application/vnd.ms-powerpoint.presentation.macroEnabled.12 application/vnd.openxmlformats-officedocument.presentationml.presentation 380 | text/calendar text/plain 381 | text/x-gettext-translation-template text/plain 382 | application/x-powershell text/plain 383 | model/mtl text/plain 384 | video/x-theora+ogg video/ogg 385 | application/x-ruby application/x-executable 386 | application/x-ruby text/plain 387 | application/rss+xml application/xml 388 | application/vnd.comicbook+zip application/zip 389 | application/x-quicktime-media-link video/quicktime 390 | application/x-mimearchive multipart/related 391 | application/vnd.mozilla.xul+xml application/xml 392 | application/x-asp text/plain 393 | application/x-xzpdf application/x-xz 394 | message/delivery-status text/plain 395 | audio/x-speex+ogg audio/ogg 396 | application/ld+json application/json 397 | application/x-bzpdf application/x-bzip2 398 | application/vnd.ms-powerpoint application/x-ole-storage 399 | application/x-ica text/plain 400 | application/vnd.oasis.opendocument.graphics application/zip 401 | text/x-kotlin text/plain 402 | image/x-portable-graymap image/x-portable-anymap 403 | application/x-it87 text/plain 404 | application/vnd.ms-publisher application/x-ole-storage 405 | text/x-csrc text/plain 406 | application/raml+yaml application/yaml 407 | application/appxbundle application/zip 408 | model/obj text/plain 409 | image/vnd.djvu+multipage image/vnd.djvu 410 | text/x-vala text/x-csrc 411 | application/x-bzip1-compressed-tar application/x-bzip1 412 | text/x-opencl-src text/x-csrc 413 | application/x-fishscript application/x-executable 414 | application/x-fishscript text/plain 415 | text/x.gcode text/plain 416 | application/vnd.google-earth.kml+xml application/xml 417 | audio/x-mpegurl text/plain 418 | application/json-patch+json application/json 419 | text/x-python3 text/x-python 420 | application/x-xbel application/xml 421 | application/x-ccmx text/plain 422 | application/x-cue text/plain 423 | text/x-lilypond text/plain 424 | text/x-c++hdr text/x-chdr 425 | application/x-nautilus-link text/plain 426 | application/x-php text/plain 427 | application/vnd.microsoft.portable-executable application/x-msdownload 428 | application/msixbundle application/zip 429 | text/enriched text/plain 430 | x-content/unix-software x-content/software 431 | application/pkix-cert+pem application/x-pem-file 432 | application/sdp text/plain 433 | text/x-texinfo text/plain 434 | text/x-scheme text/plain 435 | application/x-gerber-job application/json 436 | text/x-modelica text/plain 437 | application/x-gzpdf application/gzip 438 | text/x-devicetree-source text/plain 439 | application/xml-dtd text/plain 440 | text/x-svsrc text/x-verilog 441 | application/vnd.sun.xml.draw application/zip 442 | text/x-adasrc text/plain 443 | application/geo+json application/json 444 | application/vnd.ms-visio.drawing.main+xml application/zip 445 | text/x-apt-sources-list text/plain 446 | video/vnd.youtube.yt application/zip 447 | application/vnd.openxmlformats-officedocument.presentationml.template application/zip 448 | application/x-lrzip-compressed-tar application/x-lrzip 449 | application/vnd.apple.pkpass application/zip 450 | text/x-nfo text/x-readme 451 | image/x-kodak-dcr image/x-dcraw 452 | image/x-kodak-dcr image/tiff 453 | application/x-iso9660-appimage application/x-executable 454 | application/x-iso9660-appimage application/vnd.efi.iso 455 | text/x-go text/plain 456 | application/smil+xml application/xml 457 | application/x-mobi8-ebook application/x-palm-database 458 | text/x-chdr text/x-csrc 459 | text/x-objcsrc text/x-csrc 460 | model/iges text/plain 461 | text/rust text/plain 462 | application/appinstaller application/xml 463 | application/vnd.flatpak.ref text/plain 464 | application/x-xpinstall application/zip 465 | text/vnd.sun.j2me.app-descriptor text/plain 466 | application/x-spkac+base64 text/plain 467 | application/pkcs7-signature text/plain 468 | video/x-javafx video/x-flv 469 | application/x-eris-link+cbor application/cbor 470 | application/vnd.sun.xml.calc application/zip 471 | application/vnd.sun.xml.impress.template application/zip 472 | text/x-nim text/plain 473 | application/vnd.flatpak.repo text/plain 474 | application/vnd.oasis.opendocument.text-template application/zip 475 | application/vnd.openxmlformats-officedocument.presentationml.presentation application/zip 476 | text/x-txt2tags text/plain 477 | image/x-minolta-mrw image/x-dcraw 478 | text/jscript.encode application/x-executable 479 | image/x-kodak-k25 image/x-dcraw 480 | image/x-kodak-k25 image/tiff 481 | application/x-lzpdf application/x-lzip 482 | text/x-sass text/plain 483 | application/x-cisco-vpn-settings text/plain 484 | text/x-mpsub text/plain 485 | application/vnd.oasis.opendocument.graphics-template application/zip 486 | application/vnd.sun.xml.calc.template application/zip 487 | text/x-dsrc text/x-csrc 488 | image/x-tiff-multipage image/tiff 489 | audio/x-psflib audio/x-psf 490 | message/news text/plain 491 | image/x-panasonic-rw2 image/x-dcraw 492 | application/x-mozilla-bookmarks text/html 493 | message/disposition-notification text/plain 494 | font/otf font/ttf 495 | video/3gpp video/mp4 496 | text/turtle text/plain 497 | application/vnd.apple.keynote application/zip 498 | text/x-svhdr text/x-verilog 499 | text/tcl text/plain 500 | application/x-fluid text/plain 501 | text/x-python application/x-executable 502 | text/x-python text/plain 503 | application/x-gtk-builder application/xml 504 | text/spreadsheet text/plain 505 | text/csv-schema text/plain 506 | text/x-component application/xml 507 | application/x-sami text/plain 508 | text/x-meson text/plain 509 | application/x-bzpostscript application/x-bzip2 510 | application/x-gd-rom-cue text/plain 511 | application/x-gdscript text/plain 512 | text/x-ssa text/plain 513 | video/x-matroska application/x-matroska 514 | application/x-xz-compressed-tar application/x-xz 515 | text/x-tex text/plain 516 | application/vnd.squashfs application/vnd.efi.img 517 | -------------------------------------------------------------------------------- /src/basetype/check.rs: -------------------------------------------------------------------------------- 1 | use crate::{read_bytes, Mime}; 2 | use fnv::FnvHashMap; 3 | use std::fs::File; 4 | 5 | pub(crate) struct BaseType; 6 | 7 | impl crate::Checker for BaseType { 8 | fn match_bytes(&self, bytes: &[u8], mimetype: &str) -> bool { 9 | if mimetype == "application/octet-stream" || mimetype == "all/allfiles" { 10 | // Both of these are the case if we have a bytestream at all 11 | return true; 12 | } 13 | if mimetype == "text/plain" { 14 | is_text_plain_from_u8(bytes) 15 | } else { 16 | // ...how did we get bytes for this? 17 | false 18 | } 19 | } 20 | 21 | fn match_file(&self, file: &File, mimetype: &str) -> bool { 22 | // Being bad with error handling here, 23 | // but if you can't open it it's probably not a file. 24 | let Ok(meta) = file.metadata() else { 25 | return false; 26 | }; 27 | 28 | match mimetype { 29 | "all/all" => true, 30 | "all/allfiles" | "application/octet-stream" => meta.is_file(), 31 | "inode/directory" => meta.is_dir(), 32 | "text/plain" => is_text_plain_from_file(file), 33 | _ => false, 34 | } 35 | } 36 | 37 | fn get_supported(&self) -> Vec { 38 | super::init::get_supported() 39 | } 40 | 41 | fn get_subclasses(&self) -> Vec<(Mime, Mime)> { 42 | super::init::get_subclasses() 43 | } 44 | 45 | fn get_aliaslist(&self) -> FnvHashMap { 46 | super::init::get_aliaslist() 47 | } 48 | } 49 | 50 | /// If there are any null bytes, return False. Otherwise return True. 51 | fn is_text_plain_from_u8(bytes: &[u8]) -> bool { 52 | memchr::memchr(0, bytes).is_none() 53 | } 54 | 55 | // TODO: Hoist the main logic here somewhere else. This'll get redundant fast! 56 | fn is_text_plain_from_file(file: &File) -> bool { 57 | let Ok(bytes) = read_bytes(file, 512) else { 58 | return false; 59 | }; 60 | is_text_plain_from_u8(&bytes) 61 | } 62 | -------------------------------------------------------------------------------- /src/basetype/init.rs: -------------------------------------------------------------------------------- 1 | use crate::Mime; 2 | use fnv::FnvHashMap; 3 | 4 | pub fn get_supported() -> Vec { 5 | super::TYPES.to_vec() 6 | } 7 | 8 | /// Returns Vec of parent->child relations 9 | pub fn get_subclasses() -> Vec<(Mime, Mime)> { 10 | vec![ 11 | ("all/all", "all/allfiles"), 12 | ("all/all", "inode/directory"), 13 | ("all/allfiles", "application/octet-stream"), 14 | ("application/octet-stream", "text/plain"), 15 | ] 16 | } 17 | 18 | pub fn get_aliaslist() -> FnvHashMap { 19 | FnvHashMap::default() 20 | } 21 | -------------------------------------------------------------------------------- /src/basetype/mod.rs: -------------------------------------------------------------------------------- 1 | //! Handles "base types" such as inode/* and text/plain 2 | const TYPES: [&str; 5] = [ 3 | "all/all", 4 | "all/allfiles", 5 | "inode/directory", 6 | "text/plain", 7 | "application/octet-stream", 8 | ]; 9 | 10 | pub mod check; 11 | pub mod init; 12 | -------------------------------------------------------------------------------- /src/fdo_magic/builtin/check.rs: -------------------------------------------------------------------------------- 1 | use super::ALL_RULES; 2 | use crate::{fdo_magic::check::from_u8_walker, read_bytes, Mime}; 3 | use fnv::FnvHashMap; 4 | use petgraph::prelude::*; 5 | use std::fs::File; 6 | 7 | pub(crate) struct FdoMagic; 8 | 9 | impl crate::Checker for FdoMagic { 10 | fn match_bytes(&self, bytes: &[u8], mimetype: &str) -> bool { 11 | // Get magic ruleset 12 | let Some(graph) = ALL_RULES.get(mimetype) else { 13 | return false; 14 | }; 15 | 16 | // Check all rulesets 17 | graph 18 | .externals(Incoming) 19 | .any(|node| from_u8_walker(bytes, graph, node, true)) 20 | } 21 | 22 | fn match_file(&self, file: &File, mimetype: &str) -> bool { 23 | // Get magic ruleset 24 | let Some(magic_rules) = ALL_RULES.get(mimetype) else { 25 | return false; 26 | }; 27 | 28 | // Get # of bytes to read 29 | let scanlen = magic_rules 30 | .node_weights() 31 | .map(|rule| rule.scan_len()) 32 | .max() 33 | .unwrap_or(0); 34 | 35 | let Ok(bytes) = read_bytes(file, scanlen) else { 36 | return false; 37 | }; 38 | 39 | self.match_bytes(&bytes, mimetype) 40 | } 41 | 42 | fn get_supported(&self) -> Vec { 43 | super::init::get_supported() 44 | } 45 | 46 | fn get_subclasses(&self) -> Vec<(Mime, Mime)> { 47 | super::init::get_subclasses() 48 | } 49 | 50 | fn get_aliaslist(&self) -> FnvHashMap { 51 | super::init::get_aliaslist() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/fdo_magic/builtin/init.rs: -------------------------------------------------------------------------------- 1 | use crate::Mime; 2 | use fnv::FnvHashMap; 3 | 4 | #[cfg(not(feature = "with-gpl-data"))] 5 | use super::runtime; 6 | 7 | fn aliases() -> &'static str { 8 | #[cfg(feature = "with-gpl-data")] 9 | return tree_magic_db::aliases(); 10 | #[cfg(not(feature = "with-gpl-data"))] 11 | return runtime::aliases(); 12 | } 13 | 14 | fn subclasses() -> &'static str { 15 | #[cfg(feature = "with-gpl-data")] 16 | return tree_magic_db::subclasses(); 17 | #[cfg(not(feature = "with-gpl-data"))] 18 | return runtime::subclasses(); 19 | } 20 | 21 | pub fn get_aliaslist() -> FnvHashMap { 22 | aliases() 23 | .lines() 24 | .filter(|line| !line.is_empty()) 25 | .map(|line| { 26 | let mut parts = line.split_whitespace(); 27 | let a = parts.next().unwrap(); 28 | let b = parts.next().unwrap(); 29 | (a, b) 30 | }) 31 | .collect() 32 | } 33 | 34 | /// Get list of supported MIME types 35 | pub fn get_supported() -> Vec { 36 | super::ALL_RULES.keys().cloned().collect() 37 | } 38 | 39 | /// Get list of parent -> child subclass links 40 | pub fn get_subclasses() -> Vec<(Mime, Mime)> { 41 | subclasses() 42 | .lines() 43 | .filter(|line| !line.is_empty()) 44 | .map(|line| { 45 | let mut parts = line.split_whitespace(); 46 | 47 | let child = parts.next().unwrap(); 48 | let child = super::ALIASES.get(child).copied().unwrap_or(child); 49 | 50 | let parent = parts.next().unwrap(); 51 | let parent = super::ALIASES.get(parent).copied().unwrap_or(parent); 52 | 53 | (parent, child) 54 | }) 55 | .collect() 56 | } 57 | -------------------------------------------------------------------------------- /src/fdo_magic/builtin/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read magic file bundled in crate 2 | 3 | use super::MagicRule; 4 | use crate::Mime; 5 | use fnv::FnvHashMap; 6 | use once_cell::sync::Lazy; 7 | use petgraph::prelude::*; 8 | 9 | pub mod check; 10 | pub mod init; 11 | 12 | #[cfg(not(feature = "with-gpl-data"))] 13 | mod runtime; 14 | 15 | /// Preload alias list 16 | static ALIASES: Lazy> = Lazy::new(init::get_aliaslist); 17 | 18 | /// Load magic file before anything else. 19 | static ALL_RULES: Lazy, u32>>> = Lazy::new(|| { 20 | #[cfg(feature = "with-gpl-data")] 21 | return super::ruleset::from_u8(tree_magic_db::magic()).unwrap_or_default(); 22 | #[cfg(not(feature = "with-gpl-data"))] 23 | return runtime::rules().unwrap_or_default(); 24 | }); 25 | -------------------------------------------------------------------------------- /src/fdo_magic/builtin/runtime.rs: -------------------------------------------------------------------------------- 1 | //! Enable loading the magic database files at runtime rather than embedding the GPLed database 2 | 3 | use std::env::{split_paths, var_os}; 4 | use std::ffi::OsString; 5 | use std::fs::{read, read_to_string}; 6 | use std::path::{Path, PathBuf}; 7 | 8 | use fnv::FnvHashMap; 9 | use once_cell::sync::OnceCell; 10 | use petgraph::prelude::DiGraph; 11 | 12 | use super::MagicRule; 13 | use crate::fdo_magic::ruleset; 14 | use crate::Mime; 15 | 16 | fn mime_path(base: &Path, filename: &str) -> PathBuf { 17 | base.join("mime").join(filename) 18 | } 19 | 20 | fn search_paths(filename: &str) -> Vec { 21 | let mut paths = Vec::new(); 22 | 23 | let data_dirs = match var_os("XDG_DATA_DIRS") { 24 | Some(dirs) if !dirs.is_empty() => dirs, 25 | _ => OsString::from("/usr/local/share/:/usr/share/"), 26 | }; 27 | paths.extend(split_paths(&data_dirs).map(|base| mime_path(&base, filename))); 28 | 29 | let data_home = match var_os("XDG_DATA_HOME") { 30 | Some(data_home) if !data_home.is_empty() => Some(PathBuf::from(data_home)), 31 | _ => var_os("HOME").map(|home| Path::new(&home).join(".local/share")), 32 | }; 33 | if let Some(data_home) = data_home { 34 | paths.push(mime_path(&data_home, filename)); 35 | } 36 | 37 | #[cfg(target_os = "macos")] 38 | paths.push(mime_path(Path::new("/opt/homebrew/share"), filename)); 39 | 40 | paths 41 | } 42 | 43 | /// Load the magic database from the predefined locations in the XDG standard 44 | fn load_xdg_shared_magic() -> Vec> { 45 | search_paths("magic") 46 | .iter() 47 | .map(read) 48 | .filter_map(Result::ok) 49 | .collect() 50 | } 51 | 52 | /// Load a number of files at `paths` and concatenate them together with a newline 53 | fn load_concat_strings(filename: &str) -> String { 54 | search_paths(filename) 55 | .iter() 56 | .map(read_to_string) 57 | .filter_map(Result::ok) 58 | .collect::>() 59 | .join("\n") 60 | } 61 | 62 | pub fn aliases() -> &'static str { 63 | static ALIAS_STRING: OnceCell = OnceCell::new(); 64 | ALIAS_STRING.get_or_init(|| load_concat_strings("aliases")) 65 | } 66 | 67 | pub fn subclasses() -> &'static str { 68 | static SUBCLASS_STRING: OnceCell = OnceCell::new(); 69 | SUBCLASS_STRING.get_or_init(|| load_concat_strings("subclasses")) 70 | } 71 | 72 | pub fn rules() -> Result, u32>>, String> { 73 | static RUNTIME_RULES: OnceCell>> = OnceCell::new(); 74 | let files = RUNTIME_RULES.get_or_init(load_xdg_shared_magic); 75 | ruleset::from_multiple(files) 76 | } 77 | -------------------------------------------------------------------------------- /src/fdo_magic/check.rs: -------------------------------------------------------------------------------- 1 | use petgraph::prelude::*; 2 | use std::cmp::min; 3 | use std::iter::zip; 4 | 5 | fn from_u8_singlerule(bytes: &[u8], rule: &super::MagicRule) -> bool { 6 | // Check if we're even in bounds 7 | let bound_min = rule.start_off as usize; 8 | if bound_min > bytes.len() { 9 | return false; 10 | } 11 | let bound_max = rule.start_off as usize + rule.val.len() + rule.region_len as usize; 12 | let bound_max = min(bound_max, bytes.len()); 13 | 14 | let testarea = &bytes[bound_min..bound_max]; 15 | 16 | testarea.windows(rule.val.len()).any(|window| { 17 | // Apply mask to value 18 | match rule.mask { 19 | None => rule.val == window, 20 | Some(mask) => { 21 | assert_eq!(window.len(), mask.len()); 22 | let masked = zip(window, mask).map(|(a, b)| a & b); 23 | rule.val.iter().copied().eq(masked) 24 | } 25 | } 26 | }) 27 | } 28 | 29 | /// Test every given rule by walking graph 30 | /// TODO: Not loving the code duplication here. 31 | pub fn from_u8_walker( 32 | bytes: &[u8], 33 | graph: &DiGraph, 34 | node: NodeIndex, 35 | isroot: bool, 36 | ) -> bool { 37 | let n = graph.neighbors_directed(node, Outgoing); 38 | 39 | if isroot { 40 | let rule = &graph[node]; 41 | 42 | // Check root 43 | if !from_u8_singlerule(bytes, rule) { 44 | return false; 45 | } 46 | 47 | // Return if that was the only test 48 | if n.clone().count() == 0 { 49 | return true; 50 | } 51 | 52 | // Otherwise next indent level is lower, so continue 53 | } 54 | 55 | // Check subrules recursively 56 | for y in n { 57 | let rule = &graph[y]; 58 | 59 | if from_u8_singlerule(bytes, rule) { 60 | // Check next indent level if needed 61 | if graph.neighbors_directed(y, Outgoing).count() != 0 { 62 | return from_u8_walker(bytes, graph, y, false); 63 | // Next indent level is lower, so this must be it 64 | } else { 65 | return true; 66 | } 67 | } 68 | } 69 | 70 | false 71 | } 72 | -------------------------------------------------------------------------------- /src/fdo_magic/mod.rs: -------------------------------------------------------------------------------- 1 | // Common routines for all fdo_magic parsers 2 | 3 | pub mod builtin; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct MagicRule<'a> { 7 | indent_level: u32, 8 | start_off: u32, 9 | val: &'a [u8], 10 | mask: Option<&'a [u8]>, 11 | region_len: u32, 12 | } 13 | 14 | impl MagicRule<'_> { 15 | fn scan_len(&self) -> usize { 16 | self.start_off as usize + self.val.len() + self.region_len as usize 17 | } 18 | } 19 | 20 | mod check; 21 | mod ruleset; 22 | -------------------------------------------------------------------------------- /src/fdo_magic/ruleset.rs: -------------------------------------------------------------------------------- 1 | use super::MagicRule; 2 | 3 | use fnv::FnvHashMap; 4 | use nom::{ 5 | bytes::complete::{is_not, tag, take, take_while}, 6 | character::is_digit, 7 | combinator::{map, map_res, opt}, 8 | multi::many0, 9 | number::complete::be_u16, 10 | sequence::{delimited, preceded, terminated, tuple}, 11 | IResult, 12 | }; 13 | use petgraph::prelude::*; 14 | use std::str; 15 | 16 | // Singular magic ruleset 17 | fn magic_rules(input: &[u8]) -> IResult<&[u8], MagicRule<'_>> { 18 | let int_or = |default| { 19 | map(take_while(is_digit), move |digits| { 20 | str::from_utf8(digits).unwrap().parse().unwrap_or(default) 21 | }) 22 | }; 23 | 24 | let (input, (indent_level, start_off, val_len)) = tuple(( 25 | terminated(int_or(0), tag(">")), 26 | terminated(int_or(0), tag("=")), 27 | be_u16, 28 | ))(input)?; 29 | 30 | let (input, (val, mask, _word_len, region_len)) = terminated( 31 | tuple(( 32 | take(val_len), 33 | opt(preceded(tag("&"), take(val_len))), 34 | opt(preceded(tag("~"), int_or(1))), 35 | opt(preceded(tag("+"), int_or(0))), 36 | )), 37 | tag("\n"), 38 | )(input)?; 39 | 40 | Ok(( 41 | input, 42 | MagicRule { 43 | indent_level, 44 | start_off, 45 | val, 46 | mask, 47 | region_len: region_len.unwrap_or(0), 48 | }, 49 | )) 50 | } 51 | 52 | /// Converts a magic file given as a &[u8] array 53 | /// to a vector of MagicEntry structs 54 | fn ruleset(input: &[u8]) -> IResult<&[u8], Vec<(&str, Vec>)>> { 55 | // Parse the MIME type from "[priority: mime]" 56 | let mime = map_res( 57 | terminated( 58 | delimited( 59 | delimited(tag("["), is_not(":"), tag(":")), // priority 60 | is_not("]"), // mime 61 | tag("]"), 62 | ), 63 | tag("\n"), 64 | ), 65 | str::from_utf8, 66 | ); 67 | 68 | let magic_entry = tuple((mime, many0(magic_rules))); 69 | preceded(tag("MIME-Magic\0\n"), many0(magic_entry))(input) 70 | } 71 | 72 | fn gen_graph(magic_rules: Vec>) -> DiGraph, u32> { 73 | use petgraph::prelude::*; 74 | // Whip up a graph real quick 75 | let mut graph = DiGraph::::new(); 76 | let mut rulestack = Vec::<(MagicRule, NodeIndex)>::new(); 77 | 78 | for x in magic_rules { 79 | let xnode = graph.add_node(x.clone()); 80 | 81 | loop { 82 | let y = rulestack.pop(); 83 | match y { 84 | None => { 85 | break; 86 | } 87 | Some(rule) => { 88 | if rule.0.indent_level < x.indent_level { 89 | graph.add_edge(rule.1, xnode, 1); 90 | rulestack.push(rule); 91 | break; 92 | } 93 | } 94 | }; 95 | } 96 | rulestack.push((x, xnode)); 97 | } 98 | graph 99 | } 100 | 101 | #[cfg(feature = "with-gpl-data")] 102 | pub fn from_u8(b: &[u8]) -> Result, u32>>, String> { 103 | let tuplevec = ruleset(b).map_err(|e| e.to_string())?.1; 104 | let res = tuplevec 105 | .into_iter() 106 | .map(|x| (x.0, gen_graph(x.1))) 107 | .collect(); 108 | Ok(res) 109 | } 110 | 111 | #[cfg(not(feature = "with-gpl-data"))] 112 | /// Parse multiple ruleset magic files and aggregate the tuples into a single graph 113 | pub fn from_multiple( 114 | files: &[Vec], 115 | ) -> Result, u32>>, String> { 116 | let mut tuplevec = vec![]; 117 | for slice in files { 118 | tuplevec.append(&mut ruleset(slice.as_ref()).map_err(|e| e.to_string())?.1); 119 | } 120 | let res = tuplevec 121 | .into_iter() 122 | .map(|x| (x.0, gen_graph(x.1))) 123 | .collect(); 124 | Ok(res) 125 | } 126 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! `tree_magic_mini` is a Rust crate that determines the MIME type a given file or byte stream. 2 | //! 3 | //! This is a fork of the [tree_magic](https://crates.io/crates/tree_magic) 4 | //! crate by Allison Hancock. It includes the following changes: 5 | //! 6 | //! * Updated dependencies. 7 | //! * Reduced copying and memory allocation, for a slight increase in speed and 8 | //! decrease in memory use. 9 | //! * Reduced API surface. Some previously public APIs are now internal. 10 | //! * Removed the optional `cli` feature and `tmagic` binary. 11 | //! 12 | //! # About tree_magic 13 | //! 14 | //! `tree_magic` is designed to be more efficient and to have less false positives compared 15 | //! to the old approach used by `libmagic`, or old-fashioned file extension comparisons. 16 | //! 17 | //! Instead, this loads all known MIME types into a tree based on subclasses. Then, instead 18 | //! of checking against *every* file type, `tree_magic` will traverse down the tree and 19 | //! only check the files that make sense to check. 20 | //! 21 | //! # Features 22 | //! 23 | //! - Very fast perfomance (~150ns to check one file against one type, 24 | //! between 5,000ns and 100,000ns to find a MIME type.) 25 | //! - Check if a file *is* a certain type. 26 | //! - Handles aliases (ex: `application/zip` vs `application/x-zip-compressed`) 27 | //! - Can delegate different file types to different "checkers", reducing false positives 28 | //! by choosing a different method of attack. 29 | //! 30 | //! ## Licensing and the MIME database 31 | //! 32 | //! By default, `tree_magic_mini` will attempt to load the shared MIME info 33 | //! database from the standard locations at runtime. 34 | //! 35 | //! If you won't have the database files available, or would like to include them 36 | //! in your binary for simplicity, you can optionally embed the database 37 | //! information if you enable the `tree_magic_db` feature. 38 | //! 39 | //! **As the magic database files themselves are licensed under the GPL, you must 40 | //! make sure your project uses a compatible license if you enable this behaviour.** 41 | //! 42 | //! # Example 43 | //! ```rust 44 | //! // Load a GIF file 45 | //! let input: &[u8] = include_bytes!("../tests/image/gif"); 46 | //! 47 | //! // Find the MIME type of the GIF 48 | //! let result = tree_magic_mini::from_u8(input); 49 | //! assert_eq!(result, "image/gif"); 50 | //! 51 | //! // Check if the MIME and the file are a match 52 | //! let result = tree_magic_mini::match_u8("image/gif", input); 53 | //! assert_eq!(result, true); 54 | //! ``` 55 | 56 | use fnv::{FnvHashMap, FnvHashSet}; 57 | use once_cell::sync::Lazy; 58 | use petgraph::prelude::*; 59 | use std::fs::File; 60 | use std::io::prelude::*; 61 | use std::path::Path; 62 | 63 | mod basetype; 64 | mod fdo_magic; 65 | 66 | type Mime = &'static str; 67 | 68 | /// Check these types first 69 | /// TODO: Poll these from the checkers? Feels a bit arbitrary 70 | const TYPEORDER: [&str; 6] = [ 71 | "image/png", 72 | "image/jpeg", 73 | "image/gif", 74 | "application/zip", 75 | "application/x-msdos-executable", 76 | "application/pdf", 77 | ]; 78 | 79 | trait Checker: Send + Sync { 80 | fn match_bytes(&self, bytes: &[u8], mimetype: &str) -> bool; 81 | fn match_file(&self, file: &File, mimetype: &str) -> bool; 82 | fn get_supported(&self) -> Vec; 83 | fn get_subclasses(&self) -> Vec<(Mime, Mime)>; 84 | fn get_aliaslist(&self) -> FnvHashMap; 85 | } 86 | 87 | static CHECKERS: &[&'static dyn Checker] = &[ 88 | &fdo_magic::builtin::check::FdoMagic, 89 | &basetype::check::BaseType, 90 | ]; 91 | 92 | // Mappings between modules and supported mimes 93 | 94 | static CHECKER_SUPPORT: Lazy> = Lazy::new(|| { 95 | let mut out = FnvHashMap::::default(); 96 | for &c in CHECKERS { 97 | for m in c.get_supported() { 98 | out.insert(m, c); 99 | } 100 | } 101 | out 102 | }); 103 | 104 | static ALIASES: Lazy> = Lazy::new(|| { 105 | let mut out = FnvHashMap::::default(); 106 | for &c in CHECKERS { 107 | out.extend(c.get_aliaslist()); 108 | } 109 | out 110 | }); 111 | 112 | /// Information about currently loaded MIME types 113 | /// 114 | /// The `graph` contains subclass relations between all given mimes. 115 | /// (EX: `application/json` -> `text/plain` -> `application/octet-stream`) 116 | /// This is a `petgraph` DiGraph, so you can walk the tree if needed. 117 | /// 118 | /// The `hash` is a mapping between MIME types and nodes on the graph. 119 | /// The root of the graph is "all/all", so start traversing there unless 120 | /// you need to jump to a particular node. 121 | struct TypeStruct { 122 | graph: DiGraph, 123 | } 124 | 125 | /// The TypeStruct autogenerated at library init, and used by the library. 126 | static TYPE: Lazy = Lazy::new(|| { 127 | let mut graph = DiGraph::::new(); 128 | let mut added_mimes = FnvHashMap::::default(); 129 | 130 | // Get list of MIME types and MIME relations 131 | let mut mimelist = Vec::::new(); 132 | let mut edgelist_raw = Vec::<(Mime, Mime)>::new(); 133 | for &c in CHECKERS { 134 | mimelist.extend(c.get_supported()); 135 | edgelist_raw.extend(c.get_subclasses()); 136 | } 137 | mimelist.sort_unstable(); 138 | mimelist.dedup(); 139 | let mimelist = mimelist; 140 | 141 | // Create all nodes 142 | for mimetype in mimelist.iter() { 143 | let node = graph.add_node(mimetype); 144 | added_mimes.insert(mimetype, node); 145 | } 146 | 147 | let mut edge_list = FnvHashSet::<(NodeIndex, NodeIndex)>::with_capacity_and_hasher( 148 | edgelist_raw.len(), 149 | Default::default(), 150 | ); 151 | for (child_raw, parent_raw) in &edgelist_raw { 152 | let Some(parent) = added_mimes.get(parent_raw) else { 153 | continue; 154 | }; 155 | let Some(child) = added_mimes.get(child_raw) else { 156 | continue; 157 | }; 158 | edge_list.insert((*child, *parent)); 159 | } 160 | 161 | graph.extend_with_edges(&edge_list); 162 | 163 | //Add to applicaton/octet-stream, all/all, or text/plain, depending on top-level 164 | //(We'll just do it here because having the graph makes it really nice) 165 | let node_text = *added_mimes 166 | .entry("text/plain") 167 | .or_insert_with(|| graph.add_node("text/plain")); 168 | 169 | let node_octet = *added_mimes 170 | .entry("application/octet-stream") 171 | .or_insert_with(|| graph.add_node("application/octet-stream")); 172 | 173 | let node_allall = *added_mimes 174 | .entry("all/all") 175 | .or_insert_with(|| graph.add_node("all/all")); 176 | 177 | let node_allfiles = *added_mimes 178 | .entry("all/allfiles") 179 | .or_insert_with(|| graph.add_node("all/allfiles")); 180 | 181 | let mut edge_list_2 = FnvHashSet::<(NodeIndex, NodeIndex)>::default(); 182 | for mimenode in graph.externals(Incoming) { 183 | let mimetype = &graph[mimenode]; 184 | let toplevel = mimetype.split('/').next().unwrap_or(""); 185 | 186 | if mimenode == node_text 187 | || mimenode == node_octet 188 | || mimenode == node_allfiles 189 | || mimenode == node_allall 190 | { 191 | continue; 192 | } 193 | 194 | if toplevel == "text" { 195 | edge_list_2.insert((node_text, mimenode)); 196 | } else if toplevel == "inode" { 197 | edge_list_2.insert((node_allall, mimenode)); 198 | } else { 199 | edge_list_2.insert((node_octet, mimenode)); 200 | } 201 | } 202 | // Don't add duplicate entries 203 | graph.extend_with_edges(edge_list_2.difference(&edge_list)); 204 | 205 | TypeStruct { graph } 206 | }); 207 | 208 | /// Just the part of from_*_node that walks the graph 209 | fn typegraph_walker(parentnode: NodeIndex, input: &T, matchfn: F) -> Option 210 | where 211 | T: ?Sized, 212 | F: Fn(&str, &T) -> bool, 213 | { 214 | // Pull most common types towards top 215 | let mut children: Vec = TYPE 216 | .graph 217 | .neighbors_directed(parentnode, Outgoing) 218 | .collect(); 219 | 220 | for i in 0..children.len() { 221 | let x = children[i]; 222 | if TYPEORDER.contains(&TYPE.graph[x]) { 223 | children.remove(i); 224 | children.insert(0, x); 225 | } 226 | } 227 | 228 | // Walk graph 229 | for childnode in children { 230 | let mimetype = &TYPE.graph[childnode]; 231 | 232 | let result = matchfn(mimetype, input); 233 | match result { 234 | true => match typegraph_walker(childnode, input, matchfn) { 235 | Some(foundtype) => return Some(foundtype), 236 | None => return Some(mimetype), 237 | }, 238 | false => continue, 239 | } 240 | } 241 | 242 | None 243 | } 244 | 245 | /// Transforms an alias into it's real type 246 | fn get_alias(mimetype: &str) -> &str { 247 | match ALIASES.get(mimetype) { 248 | Some(x) => x, 249 | None => mimetype, 250 | } 251 | } 252 | 253 | /// Internal function. Checks if an alias exists, and if it does, 254 | /// then runs `match_bytes`. 255 | fn match_u8_noalias(mimetype: &str, bytes: &[u8]) -> bool { 256 | match CHECKER_SUPPORT.get(mimetype) { 257 | None => false, 258 | Some(y) => y.match_bytes(bytes, mimetype), 259 | } 260 | } 261 | 262 | /// Checks if the given bytestream matches the given MIME type. 263 | /// 264 | /// Returns true or false if it matches or not. If the given MIME type is not known, 265 | /// the function will always return false. 266 | /// If mimetype is an alias of a known MIME, the file will be checked agains that MIME. 267 | /// 268 | /// # Examples 269 | /// ```rust 270 | /// // Load a GIF file 271 | /// let input: &[u8] = include_bytes!("../tests/image/gif"); 272 | /// 273 | /// // Check if the MIME and the file are a match 274 | /// let result = tree_magic_mini::match_u8("image/gif", input); 275 | /// assert_eq!(result, true); 276 | /// ``` 277 | pub fn match_u8(mimetype: &str, bytes: &[u8]) -> bool { 278 | match_u8_noalias(get_alias(mimetype), bytes) 279 | } 280 | 281 | /// Gets the type of a file from a raw bytestream, starting at a certain node 282 | /// in the type graph. 283 | /// 284 | /// Returns MIME as string wrapped in Some if a type matches, or 285 | /// None if no match is found under the given node. 286 | /// Retreive the node from the `TYPE.hash` HashMap, using the MIME as the key. 287 | /// 288 | /// # Panics 289 | /// Will panic if the given node is not found in the graph. 290 | /// As the graph is immutable, this should not happen if the node index comes from 291 | /// TYPE.hash. 292 | fn from_u8_node(parentnode: NodeIndex, bytes: &[u8]) -> Option { 293 | typegraph_walker(parentnode, bytes, match_u8_noalias) 294 | } 295 | 296 | /// Gets the type of a file from a byte stream. 297 | /// 298 | /// Returns MIME as string. 299 | /// 300 | /// # Examples 301 | /// ```rust 302 | /// // Load a GIF file 303 | /// let input: &[u8] = include_bytes!("../tests/image/gif"); 304 | /// 305 | /// // Find the MIME type of the GIF 306 | /// let result = tree_magic_mini::from_u8(input); 307 | /// assert_eq!(result, "image/gif"); 308 | /// ``` 309 | pub fn from_u8(bytes: &[u8]) -> Mime { 310 | let node = match TYPE.graph.externals(Incoming).next() { 311 | Some(foundnode) => foundnode, 312 | None => panic!("No filetype definitions are loaded."), 313 | }; 314 | from_u8_node(node, bytes).unwrap() 315 | } 316 | 317 | /// Check if the given file matches the given MIME type. 318 | /// 319 | /// # Examples 320 | /// ```rust 321 | /// use std::fs::File; 322 | /// 323 | /// // Get path to a GIF file 324 | /// let file = File::open("tests/image/gif").unwrap(); 325 | /// 326 | /// // Check if the MIME and the file are a match 327 | /// let result = tree_magic_mini::match_file("image/gif", &file); 328 | /// assert_eq!(result, true); 329 | /// ``` 330 | pub fn match_file(mimetype: &str, file: &File) -> bool { 331 | match_file_noalias(get_alias(mimetype), file) 332 | } 333 | 334 | /// Internal function. Checks if an alias exists, and if it does, 335 | /// then runs `match_file`. 336 | fn match_file_noalias(mimetype: &str, file: &File) -> bool { 337 | match CHECKER_SUPPORT.get(mimetype) { 338 | None => false, 339 | Some(c) => c.match_file(file, mimetype), 340 | } 341 | } 342 | 343 | /// Check if the file at the given path matches the given MIME type. 344 | /// 345 | /// Returns false if the file could not be read or the given MIME type is not known. 346 | /// 347 | /// # Examples 348 | /// ```rust 349 | /// use std::path::Path; 350 | /// 351 | /// // Get path to a GIF file 352 | /// let path: &Path = Path::new("tests/image/gif"); 353 | /// 354 | /// // Check if the MIME and the file are a match 355 | /// let result = tree_magic_mini::match_filepath("image/gif", path); 356 | /// assert_eq!(result, true); 357 | /// ``` 358 | #[inline] 359 | pub fn match_filepath(mimetype: &str, path: &Path) -> bool { 360 | let Ok(file) = File::open(path) else { 361 | return false; 362 | }; 363 | match_file(mimetype, &file) 364 | } 365 | 366 | /// Gets the type of a file, starting at a certain node in the type graph. 367 | fn from_file_node(parentnode: NodeIndex, file: &File) -> Option { 368 | // We're actually just going to thunk this down to a u8 369 | // unless we're checking via basetype for speed reasons. 370 | 371 | // Ensure it's at least a application/octet-stream 372 | if !match_file("application/octet-stream", file) { 373 | // Check the other base types 374 | return typegraph_walker(parentnode, file, match_file_noalias); 375 | } 376 | 377 | // Load the first 2K of file and parse as u8 378 | // for batch processing like this 379 | let bytes = read_bytes(file, 2048).ok()?; 380 | from_u8_node(parentnode, &bytes) 381 | } 382 | 383 | /// Gets the MIME type of a file. 384 | /// 385 | /// Does not look at file name or extension, just the contents. 386 | /// 387 | /// # Examples 388 | /// ```rust 389 | /// use std::fs::File; 390 | /// 391 | /// // Get path to a GIF file 392 | /// let file = File::open("tests/image/gif").unwrap(); 393 | /// 394 | /// // Find the MIME type of the GIF 395 | /// let result = tree_magic_mini::from_file(&file); 396 | /// assert_eq!(result, Some("image/gif")); 397 | /// ``` 398 | pub fn from_file(file: &File) -> Option { 399 | let node = TYPE.graph.externals(Incoming).next()?; 400 | from_file_node(node, file) 401 | } 402 | 403 | /// Gets the MIME type of a file. 404 | /// 405 | /// Does not look at file name or extension, just the contents. 406 | /// Returns None if the file cannot be opened 407 | /// or if no matching MIME type is found. 408 | /// 409 | /// # Examples 410 | /// ```rust 411 | /// use std::path::Path; 412 | /// 413 | /// // Get path to a GIF file 414 | /// let path = Path::new("tests/image/gif"); 415 | /// 416 | /// // Find the MIME type of the GIF 417 | /// let result = tree_magic_mini::from_filepath(path); 418 | /// assert_eq!(result, Some("image/gif")); 419 | /// ``` 420 | #[inline] 421 | pub fn from_filepath(path: &Path) -> Option { 422 | let file = File::open(path).ok()?; 423 | from_file(&file) 424 | } 425 | 426 | /// Reads the given number of bytes from a file 427 | fn read_bytes(file: &File, bytecount: usize) -> Result, std::io::Error> { 428 | let mut bytes = Vec::::with_capacity(bytecount); 429 | file.take(bytecount as u64).read_to_end(&mut bytes)?; 430 | Ok(bytes) 431 | } 432 | -------------------------------------------------------------------------------- /tests/application/x-7z-compressed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/application/x-7z-compressed -------------------------------------------------------------------------------- /tests/application/x-tar: -------------------------------------------------------------------------------- 1 | plain000644 001750 000144 00000000035 13073323120 012722 0ustar00valerieusers000000 000000 This is just standard text. 2 | -------------------------------------------------------------------------------- /tests/application/zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/application/zip -------------------------------------------------------------------------------- /tests/audio/flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/audio/flac -------------------------------------------------------------------------------- /tests/audio/mpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/audio/mpeg -------------------------------------------------------------------------------- /tests/audio/ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/audio/ogg -------------------------------------------------------------------------------- /tests/audio/opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/audio/opus -------------------------------------------------------------------------------- /tests/audio/wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/audio/wav -------------------------------------------------------------------------------- /tests/from_filepath.rs: -------------------------------------------------------------------------------- 1 | mod from_filepath { 2 | use std::path::Path; 3 | use tree_magic_mini as tree_magic; 4 | 5 | #[test] 6 | fn nonexistent_file_returns_none() { 7 | assert_eq!( 8 | tree_magic::from_filepath(Path::new("this/file/does/not/exist")), 9 | None 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/from_u8.rs: -------------------------------------------------------------------------------- 1 | mod from_u8 { 2 | use tree_magic_mini as tree_magic; 3 | 4 | macro_rules! convmime { 5 | ($x:expr) => { 6 | $x.to_string() 7 | }; 8 | } 9 | 10 | ///Image tests 11 | #[test] 12 | fn image_heic() { 13 | assert_eq!( 14 | tree_magic::from_u8(include_bytes!("image/heic")), 15 | convmime!("image/heif") 16 | ); 17 | } 18 | #[test] 19 | fn image_gif() { 20 | assert_eq!( 21 | tree_magic::from_u8(include_bytes!("image/gif")), 22 | convmime!("image/gif") 23 | ); 24 | } 25 | #[test] 26 | fn image_png() { 27 | assert_eq!( 28 | tree_magic::from_u8(include_bytes!("image/png")), 29 | convmime!("image/png") 30 | ); 31 | } 32 | #[test] 33 | // GNU file reports image/x-ms-bmp 34 | fn image_bmp() { 35 | assert_eq!( 36 | tree_magic::from_u8(include_bytes!("image/bmp")), 37 | convmime!("image/bmp") 38 | ); 39 | } 40 | #[test] 41 | fn image_tiff() { 42 | assert_eq!( 43 | tree_magic::from_u8(include_bytes!("image/tiff")), 44 | convmime!("image/tiff") 45 | ); 46 | } 47 | #[test] 48 | fn image_x_portable_bitmap() { 49 | assert_eq!( 50 | tree_magic::from_u8(include_bytes!("image/x-portable-bitmap")), 51 | convmime!("image/x-portable-bitmap") 52 | ); 53 | } 54 | #[test] 55 | fn image_x_pcx() { 56 | assert_eq!( 57 | tree_magic::from_u8(include_bytes!("image/x-pcx")), 58 | convmime!("image/vnd.zbrush.pcx") 59 | ); 60 | } 61 | #[test] 62 | fn image_x_tga() { 63 | assert_eq!( 64 | tree_magic::from_u8(include_bytes!("image/x-tga")), 65 | convmime!("image/x-tga") 66 | ); 67 | } 68 | 69 | /// Archive tests 70 | #[test] 71 | fn application_tar() { 72 | assert_eq!( 73 | tree_magic::from_u8(include_bytes!("application/x-tar")), 74 | convmime!("application/x-tar") 75 | ); 76 | } 77 | #[test] 78 | fn application_x_7z() { 79 | assert_eq!( 80 | tree_magic::from_u8(include_bytes!("application/x-7z-compressed")), 81 | convmime!("application/x-7z-compressed") 82 | ); 83 | } 84 | #[test] 85 | fn application_zip() { 86 | assert_eq!( 87 | tree_magic::from_u8(include_bytes!("application/zip")), 88 | convmime!("application/zip") 89 | ); 90 | } 91 | 92 | /// Text tests 93 | #[test] 94 | fn text_html() { 95 | assert_eq!( 96 | tree_magic::from_u8(include_bytes!("text/html")), 97 | convmime!("text/html") 98 | ); 99 | } 100 | 101 | #[test] 102 | fn text_plain() { 103 | assert_eq!( 104 | tree_magic::from_u8(include_bytes!("text/plain")), 105 | convmime!("text/plain") 106 | ); 107 | } 108 | 109 | // Audio tests 110 | #[test] 111 | fn audio_flac() { 112 | assert_eq!( 113 | tree_magic::from_u8(include_bytes!("audio/flac")), 114 | convmime!("audio/flac") 115 | ); 116 | } 117 | 118 | #[test] 119 | fn audio_mpeg() { 120 | assert_eq!( 121 | tree_magic::from_u8(include_bytes!("audio/mpeg")), 122 | convmime!("audio/mpeg") 123 | ); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /tests/image/bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/bmp -------------------------------------------------------------------------------- /tests/image/gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/gif -------------------------------------------------------------------------------- /tests/image/heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/heic -------------------------------------------------------------------------------- /tests/image/png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/png -------------------------------------------------------------------------------- /tests/image/tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/tiff -------------------------------------------------------------------------------- /tests/image/x-pcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/x-pcx -------------------------------------------------------------------------------- /tests/image/x-portable-bitmap: -------------------------------------------------------------------------------- 1 | P4 2 | 1 1 3 | -------------------------------------------------------------------------------- /tests/image/x-tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbrubeck/tree_magic/0976b4effc2a38f421aad260bb3a4e2c23303109/tests/image/x-tga -------------------------------------------------------------------------------- /tests/image/xbm: -------------------------------------------------------------------------------- 1 | #define xbm_width 1 2 | #define xbm_height 1 3 | static unsigned char xbm_bits[] = { 4 | 0x00 }; 5 | -------------------------------------------------------------------------------- /tests/match_u8.rs: -------------------------------------------------------------------------------- 1 | mod match_u8 { 2 | use tree_magic_mini as tree_magic; 3 | 4 | ///Image tests 5 | #[test] 6 | fn image_heic() { 7 | assert!(tree_magic::match_u8( 8 | "image/heif", 9 | include_bytes!("image/heic") 10 | )); 11 | } 12 | #[test] 13 | fn image_gif() { 14 | assert!(tree_magic::match_u8( 15 | "image/gif", 16 | include_bytes!("image/gif") 17 | )); 18 | } 19 | #[test] 20 | fn image_png() { 21 | assert!(tree_magic::match_u8( 22 | "image/png", 23 | include_bytes!("image/png") 24 | )); 25 | } 26 | #[test] 27 | // GNU file reports as image/x-ms-bmp 28 | fn image_x_bmp() { 29 | assert!(tree_magic::match_u8( 30 | "image/bmp", 31 | include_bytes!("image/bmp") 32 | )); 33 | } 34 | #[test] 35 | fn image_tiff() { 36 | assert!(tree_magic::match_u8( 37 | "image/tiff", 38 | include_bytes!("image/tiff") 39 | )); 40 | } 41 | #[test] 42 | fn image_x_portable_bitmap() { 43 | assert!(tree_magic::match_u8( 44 | "image/x-portable-bitmap", 45 | include_bytes!("image/x-portable-bitmap") 46 | )); 47 | } 48 | #[test] 49 | fn image_x_pcx() { 50 | assert!(tree_magic::match_u8( 51 | "image/x-pcx", 52 | include_bytes!("image/x-pcx") 53 | )); 54 | } 55 | #[test] 56 | fn image_x_tga() { 57 | assert!(tree_magic::match_u8( 58 | "image/x-tga", 59 | include_bytes!("image/x-tga") 60 | )); 61 | } 62 | 63 | /// Archive tests 64 | #[test] 65 | fn application_tar() { 66 | assert!(tree_magic::match_u8( 67 | "application/x-tar", 68 | include_bytes!("application/x-tar") 69 | )); 70 | } 71 | #[test] 72 | fn application_x_7z() { 73 | assert!(tree_magic::match_u8( 74 | "application/x-7z-compressed", 75 | include_bytes!("application/x-7z-compressed") 76 | )); 77 | } 78 | #[test] 79 | fn application_zip() { 80 | assert!(tree_magic::match_u8( 81 | "application/zip", 82 | include_bytes!("application/zip") 83 | )); 84 | } 85 | 86 | /// Text tests 87 | #[test] 88 | fn text_plain() { 89 | assert!(tree_magic::match_u8( 90 | "text/plain", 91 | include_bytes!("text/plain") 92 | )); 93 | } 94 | 95 | // Audio tests 96 | #[test] 97 | fn audio_flac() { 98 | assert!(tree_magic::match_u8( 99 | "audio/flac", 100 | include_bytes!("audio/flac") 101 | )); 102 | } 103 | #[test] 104 | fn audio_mpeg() { 105 | assert!(tree_magic::match_u8( 106 | "audio/mpeg", 107 | include_bytes!("audio/mpeg") 108 | )); 109 | } 110 | #[test] 111 | fn audio_ogg() { 112 | assert!(tree_magic::match_u8( 113 | "audio/ogg", 114 | include_bytes!("audio/ogg") 115 | )); 116 | } 117 | #[test] 118 | fn audio_wav() { 119 | assert!(tree_magic::match_u8( 120 | "audio/wav", 121 | include_bytes!("audio/wav") 122 | )); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /tests/text/html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/text/plain: -------------------------------------------------------------------------------- 1 | This is just standard text. 2 | --------------------------------------------------------------------------------