Coder Social home page Coder Social logo

infer's Introduction

infer

Build Status crates version documentation

Small crate to infer file and MIME type by checking the magic number signature.

Adaptation of filetype Go package ported to Rust.

Does not require magic file database (i.e. /etc/magic).

Features

  • Supports a wide range of file types
  • Provides file extension and MIME type
  • File discovery by extension or MIME type
  • File discovery by class (image, video, audio...)
  • Supports custom new types and matchers

Installation

This crate works with Cargo and is on crates.io. Add it to your Cargo.toml like so:

[dependencies]
infer = "0.3"

If you are not using the custom matcher or the file type from file path functionality you can make this crate even lighter by importing it with no default features, like so:

[dependencies]
infer = { version = "0.3", default-features = false }

no_std and no_alloc support

This crate supports no_std and no_alloc environments. std support is enabled by default, but you can disable it by importing the crate with no default features, making it depend only on the Rust core Library.

alloc has to be enabled to be able to use custom file matchers.

std has to be enabled to be able to get the file type from a file given the file path.

Examples

Most operations can be done via top level functions, but they are also available through the Infer struct, which must be used when dealing custom matchers.

Get the type of a buffer

let buf = [0xFF, 0xD8, 0xFF, 0xAA];
let kind = infer::get(&buf).expect("file type is known");

assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");

Check file type by path

let kind = infer::get_from_path("testdata/sample.jpg")
    .expect("file read successfully")
    .expect("file type is known");

assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");

Check for specific type

let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::image::is_jpeg(&buf));

Check for specific type class

let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::is_image(&buf));

Adds a custom file type matcher

fn custom_matcher(buf: &[u8]) -> bool {
    return buf.len() >= 3 && buf[0] == 0x10 && buf[1] == 0x11 && buf[2] == 0x12;
}

let mut info = infer::Infer::new();
info.add("custom/foo", "foo", custom_matcher);

let buf = [0x10, 0x11, 0x12, 0x13];
let kind = info.get(&buf).expect("file type is known");

assert_eq!(kind.mime_type(), "custom/foo");
assert_eq!(kind.extension(), "foo");

Supported types

Image

  • jpg - image/jpeg
  • png - image/png
  • gif - image/gif
  • webp - image/webp
  • cr2 - image/x-canon-cr2
  • tif - image/tiff
  • bmp - image/bmp
  • heif - image/heif
  • avif - image/avif
  • jxr - image/vnd.ms-photo
  • psd - image/vnd.adobe.photoshop
  • ico - image/vnd.microsoft.icon
  • ora - image/openraster

Video

  • mp4 - video/mp4
  • m4v - video/x-m4v
  • mkv - video/x-matroska
  • webm - video/webm
  • mov - video/quicktime
  • avi - video/x-msvideo
  • wmv - video/x-ms-wmv
  • mpg - video/mpeg
  • flv - video/x-flv

Audio

  • mid - audio/midi
  • mp3 - audio/mpeg
  • m4a - audio/m4a
  • ogg - audio/ogg
  • flac - audio/x-flac
  • wav - audio/x-wav
  • amr - audio/amr
  • aac - audio/aac
  • aiff - audio/x-aiff
  • dsf - audio/x-dsf
  • ape - audio/x-ape

Archive

  • epub - application/epub+zip
  • zip - application/zip
  • tar - application/x-tar
  • rar - application/vnd.rar
  • gz - application/gzip
  • bz2 - application/x-bzip2
  • 7z - application/x-7z-compressed
  • xz - application/x-xz
  • pdf - application/pdf
  • swf - application/x-shockwave-flash
  • rtf - application/rtf
  • eot - application/octet-stream
  • ps - application/postscript
  • sqlite - application/vnd.sqlite3
  • nes - application/x-nintendo-nes-rom
  • crx - application/x-google-chrome-extension
  • cab - application/vnd.ms-cab-compressed
  • deb - application/vnd.debian.binary-package
  • ar - application/x-unix-archive
  • Z - application/x-compress
  • lz - application/x-lzip
  • rpm - application/x-rpm
  • dcm - application/dicom
  • zst - application/zstd
  • msi - application/x-ole-storage
  • cpio - application/x-cpio

Book

  • epub - application/epub+zip
  • mobi - application/x-mobipocket-ebook

Documents

  • doc - application/msword
  • docx - application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • xls - application/vnd.ms-excel
  • xlsx - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  • ppt - application/vnd.ms-powerpoint
  • pptx - application/vnd.openxmlformats-officedocument.presentationml.presentation
  • odt - application/vnd.oasis.opendocument.text
  • ods - application/vnd.oasis.opendocument.spreadsheet
  • odp - application/vnd.oasis.opendocument.presentation

Font

  • woff - application/font-woff
  • woff2 - application/font-woff
  • ttf - application/font-sfnt
  • otf - application/font-sfnt

Application

  • wasm - application/wasm
  • exe - application/vnd.microsoft.portable-executable
  • dll - application/vnd.microsoft.portable-executable
  • elf - application/x-executable
  • bc - application/llvm
  • mach - application/x-mach-binary
  • class - application/java
  • dex - application/vnd.android.dex
  • dey - application/vnd.android.dey
  • der - application/x-x509-ca-cert
  • obj - application/x-executable

Known Issues

  • exe and dll have the same magic number so it's not possible to tell which one just based on the binary data. exe is returned for all.

License

MIT

infer's People

Contributors

0x1793d1 avatar alyoshavasilieva avatar atul9 avatar bojand avatar bulkin avatar chrsmth avatar criminosis avatar deuill avatar ebkalderon avatar evensolberg avatar hannesbraun avatar kailes avatar lynnesbian avatar marcospb19 avatar mercxry avatar messense avatar paolobarbolini avatar qarmin avatar ririsoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

infer's Issues

Tests are failing on 12.0 (16 passed; 10 failed)

$ cargo test

    Finished test [unoptimized + debuginfo] target(s) in 0.01s
     Running unittests src/lib.rs (target/debug/deps/infer-90539309f54f4e10)

running 7 tests
test matchers::text::tests::html ... ok
test matchers::text::tests::shellscript ... ok
test matchers::text::tests::trim_whitespaces ... ok
test tests::test_custom_matcher_ordering ... ok
test tests::test_get_jpeg ... ok
test tests::test_get_unknown ... ok
test tests::test_matcher_type ... ok

test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests infer

running 26 tests
test src/lib.rs - (line 19) ... ok
test src/lib.rs - (line 49) ... ok
test src/lib.rs - (line 33) ... ok
test src/lib.rs - (line 40) ... ok
test src/lib.rs - Infer::is_custom (line 369) ... ok
test src/lib.rs - (line 8) ... ok
test src/lib.rs - Infer::add (line 393) ... ok
test src/lib.rs - Infer::get (line 222) ... ok
test src/lib.rs - Type::matcher_type (line 137) ... ok
test src/lib.rs - get (line 434) ... ok
test src/lib.rs - is (line 471) ... ok
test src/lib.rs - get_from_path (line 454) ... FAILED
test src/lib.rs - is_archive (line 528) ... FAILED
test src/lib.rs - is_app (line 517) ... FAILED
test src/lib.rs - is_audio (line 540) ... ok
test src/lib.rs - is_book (line 553) ... FAILED
test src/lib.rs - is_document (line 565) ... FAILED
test src/lib.rs - is_image (line 589) ... ok
test src/lib.rs - is_font (line 577) ... FAILED
test src/lib.rs - is_mime (line 483) ... ok
test src/lib.rs - is_mime_supported (line 506) ... ok
test src/lib.rs - is_supported (line 495) ... ok
test src/matchers/app.rs - matchers::app::is_exe (line 27) ... FAILED
test src/lib.rs - is_video (line 601) ... FAILED
test src/matchers/app.rs - matchers::app::is_wasm (line 5) ... FAILED
test src/matchers/archive.rs - matchers::archive::is_sqlite (line 136) ... FAILED

failures:

---- src/lib.rs - get_from_path (line 454) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'file read successfully: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:6
stack backtrace:
   0:     0x55a8480ab57c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x55a8480ab57c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x55a8480ab57c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x55a8480ab57c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x55a8480bbf0e - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x55a84808cc91 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x55a8480976be - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x55a8480976be - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x55a8480976be - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x55a848097327 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x55a848097bd1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x55a8480ab8b7 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x55a8480ab694 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x55a848097882 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x55a84804a633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x55a84804a6c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x55a84804b892 - core::result::Result<T,E>::expect::hd1d6cd5651f88740
  17:     0x55a84804c2c5 - rust_out::main::_doctest_main_src_lib_rs_454_0::h22b1c6e321286c9f
  18:     0x55a84804c276 - rust_out::main::h557bfc7675621915
  19:     0x55a84804b513 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x55a84804ab49 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x55a84804b429 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x55a84808c695 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x55a84808c695 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x55a84808c695 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x55a84808c695 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x55a84808c695 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x55a84808c695 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x55a84808c695 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x55a84808c695 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x55a84808c695 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x55a84804b411 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x55a84804c453 - main
  33:     0x7fbee9ca218a - <unknown>
  34:     0x7fbee9ca2245 - __libc_start_main
  35:     0x55a84804a7e1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_archive (line 528) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:60
stack backtrace:
   0:     0x5569879ca05c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x5569879ca05c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5569879ca05c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x5569879ca05c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x5569879da9ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x5569879ab561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x5569879b5f8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x5569879b5f8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x5569879b5f8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x5569879b5bf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x5569879b64a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x5569879ca397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x5569879ca174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x5569879b6152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x55698796a633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x55698796a6c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x55698796ab13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x55698796aba0 - rust_out::main::_doctest_main_src_lib_rs_528_0::h6fec517979542f4b
  18:     0x55698796ab66 - rust_out::main::h557bfc7675621915
  19:     0x55698796aa73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x55698796a8b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x55698796a9a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x5569879aaf65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x5569879aaf65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x5569879aaf65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x5569879aaf65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x5569879aaf65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x5569879aaf65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x5569879aaf65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x5569879aaf65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x5569879aaf65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x55698796a991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x55698796ac63 - main
  33:     0x7f30680ae18a - <unknown>
  34:     0x7f30680ae245 - __libc_start_main
  35:     0x55698796a7e1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_app (line 517) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:57
stack backtrace:
   0:     0x55e3815b205c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x55e3815b205c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x55e3815b205c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x55e3815b205c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x55e3815c29ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x55e381593561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x55e38159df8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x55e38159df8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x55e38159df8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x55e38159dbf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x55e38159e4a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x55e3815b2397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x55e3815b2174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x55e38159e152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x55e381552633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x55e3815526c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x55e381552b13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x55e381552ba0 - rust_out::main::_doctest_main_src_lib_rs_517_0::hc2a12f80ebbfbc03
  18:     0x55e381552b66 - rust_out::main::h557bfc7675621915
  19:     0x55e381552a73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x55e3815528b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x55e3815529a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x55e381592f65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x55e381592f65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x55e381592f65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x55e381592f65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x55e381592f65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x55e381592f65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x55e381592f65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x55e381592f65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x55e381592f65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x55e381552991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x55e381552c63 - main
  33:     0x7f2b2f37718a - <unknown>
  34:     0x7f2b2f377245 - __libc_start_main
  35:     0x55e3815527e1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_book (line 553) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:58
stack backtrace:
   0:     0x556d8b44905c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x556d8b44905c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x556d8b44905c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x556d8b44905c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x556d8b4599ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x556d8b42a561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x556d8b434f8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x556d8b434f8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x556d8b434f8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x556d8b434bf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x556d8b4354a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x556d8b449397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x556d8b449174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x556d8b435152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x556d8b3e9633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x556d8b3e96c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x556d8b3e9b13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x556d8b3e9ba0 - rust_out::main::_doctest_main_src_lib_rs_553_0::hd2d8bf01ecaf6c88
  18:     0x556d8b3e9b66 - rust_out::main::h557bfc7675621915
  19:     0x556d8b3e9a73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x556d8b3e98b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x556d8b3e99a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x556d8b429f65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x556d8b429f65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x556d8b429f65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x556d8b429f65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x556d8b429f65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x556d8b429f65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x556d8b429f65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x556d8b429f65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x556d8b429f65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x556d8b3e9991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x556d8b3e9c63 - main
  33:     0x7f6f1c06218a - <unknown>
  34:     0x7f6f1c062245 - __libc_start_main
  35:     0x556d8b3e97e1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_document (line 565) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:62
stack backtrace:
   0:     0x560ea89dd05c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x560ea89dd05c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x560ea89dd05c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x560ea89dd05c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x560ea89ed9ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x560ea89be561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x560ea89c8f8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x560ea89c8f8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x560ea89c8f8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x560ea89c8bf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x560ea89c94a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x560ea89dd397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x560ea89dd174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x560ea89c9152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x560ea897d633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x560ea897d6c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x560ea897db13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x560ea897dba0 - rust_out::main::_doctest_main_src_lib_rs_565_0::h489a594d4c01e7bc
  18:     0x560ea897db66 - rust_out::main::h557bfc7675621915
  19:     0x560ea897da73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x560ea897d8b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x560ea897d9a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x560ea89bdf65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x560ea89bdf65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x560ea89bdf65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x560ea89bdf65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x560ea89bdf65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x560ea89bdf65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x560ea89bdf65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x560ea89bdf65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x560ea89bdf65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x560ea897d991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x560ea897dc63 - main
  33:     0x7f95b528a18a - <unknown>
  34:     0x7f95b528a245 - __libc_start_main
  35:     0x560ea897d7e1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_font (line 577) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:57
stack backtrace:
   0:     0x56499282705c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x56499282705c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x56499282705c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x56499282705c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x5649928379ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x564992808561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x564992812f8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x564992812f8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x564992812f8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x564992812bf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x5649928134a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x564992827397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x564992827174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x564992813152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x5649927c7633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x5649927c76c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x5649927c7b13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x5649927c7ba0 - rust_out::main::_doctest_main_src_lib_rs_577_0::h327b332dc06b8847
  18:     0x5649927c7b66 - rust_out::main::h557bfc7675621915
  19:     0x5649927c7a73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x5649927c78b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x5649927c79a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x564992807f65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x564992807f65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x564992807f65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x564992807f65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x564992807f65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x564992807f65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x564992807f65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x564992807f65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x564992807f65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x5649927c7991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x5649927c7c63 - main
  33:     0x7fa5f619b18a - <unknown>
  34:     0x7fa5f619b245 - __libc_start_main
  35:     0x5649927c77e1 - _start
  36:                0x0 - <unknown>


---- src/matchers/app.rs - matchers::app::is_exe (line 27) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/matchers/app.rs:5:61
stack backtrace:
   0:     0x560f2d9478fc - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x560f2d9478fc - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x560f2d9478fc - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x560f2d9478fc - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x560f2d956fae - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x560f2d928f31 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x560f2d93395e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x560f2d93395e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x560f2d93395e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x560f2d9335c7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x560f2d933e71 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x560f2d947c37 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x560f2d947a14 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x560f2d933b22 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x560f2d923623 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x560f2d9236b3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x560f2d923b03 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x560f2d923b90 - rust_out::main::_doctest_main_src_matchers_app_rs_27_0::h634a05860a3e7f43
  18:     0x560f2d923b56 - rust_out::main::h557bfc7675621915
  19:     0x560f2d923a63 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x560f2d9238a9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x560f2d923999 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x560f2d928935 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x560f2d928935 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x560f2d928935 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x560f2d928935 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x560f2d928935 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x560f2d928935 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x560f2d928935 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x560f2d928935 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x560f2d928935 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x560f2d923981 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x560f2d923c53 - main
  33:     0x7fc4fd32018a - <unknown>
  34:     0x7fc4fd320245 - __libc_start_main
  35:     0x560f2d9237d1 - _start
  36:                0x0 - <unknown>


---- src/lib.rs - is_video (line 601) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:58
stack backtrace:
   0:     0x560550f1805c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x560550f1805c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x560550f1805c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x560550f1805c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x560550f289ee - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x560550ef9561 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x560550f03f8e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x560550f03f8e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x560550f03f8e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x560550f03bf7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x560550f044a1 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x560550f18397 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x560550f18174 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x560550f04152 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x560550eb8633 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x560550eb86c3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x560550eb8b13 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x560550eb8ba0 - rust_out::main::_doctest_main_src_lib_rs_601_0::hebb0f2d703d65633
  18:     0x560550eb8b66 - rust_out::main::h557bfc7675621915
  19:     0x560550eb8a73 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x560550eb88b9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x560550eb89a9 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x560550ef8f65 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x560550ef8f65 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x560550ef8f65 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x560550ef8f65 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x560550ef8f65 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x560550ef8f65 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x560550ef8f65 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x560550ef8f65 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x560550ef8f65 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x560550eb8991 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x560550eb8c63 - main
  33:     0x7fa303fa518a - <unknown>
  34:     0x7fa303fa5245 - __libc_start_main
  35:     0x560550eb87e1 - _start
  36:                0x0 - <unknown>


---- src/matchers/app.rs - matchers::app::is_wasm (line 5) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/matchers/app.rs:5:63
stack backtrace:
   0:     0x560da2a63aec - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x560da2a63aec - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x560da2a63aec - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x560da2a63aec - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x560da2a7319e - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x560da2a45121 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x560da2a4fb4e - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x560da2a4fb4e - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x560da2a4fb4e - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x560da2a4f7b7 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x560da2a50061 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x560da2a63e27 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x560da2a63c04 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x560da2a4fd12 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x560da2a3f623 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x560da2a3f6b3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x560da2a3fb03 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x560da2a3fb90 - rust_out::main::_doctest_main_src_matchers_app_rs_5_0::hcedebbf6d01f6ccc
  18:     0x560da2a3fb56 - rust_out::main::h557bfc7675621915
  19:     0x560da2a3fa63 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x560da2a3f8a9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x560da2a3f999 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x560da2a44b25 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x560da2a44b25 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x560da2a44b25 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x560da2a44b25 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x560da2a44b25 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x560da2a44b25 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x560da2a44b25 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x560da2a44b25 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x560da2a44b25 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x560da2a3f981 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x560da2a3fc53 - main
  33:     0x7f8566f8f18a - <unknown>
  34:     0x7f8566f8f245 - __libc_start_main
  35:     0x560da2a3f7d1 - _start
  36:                0x0 - <unknown>


---- src/matchers/archive.rs - matchers::archive::is_sqlite (line 136) stdout ----
Test executable failed (exit status: 101).

stderr:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/matchers/archive.rs:5:67
stack backtrace:
   0:     0x559d4263899c - std::backtrace_rs::backtrace::libunwind::trace::he2ba3a4891b10ef3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x559d4263899c - std::backtrace_rs::backtrace::trace_unsynchronized::ha0fda2e57da4b2a3
                               at /usr/src/rustc-1.63.0/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x559d4263899c - std::sys_common::backtrace::_print_fmt::hbfe6e1f0cd4bb862
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:66:5
   3:     0x559d4263899c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h82b6828459151f7c
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:45:22
   4:     0x559d4264804e - core::fmt::write::hafcd92e27b23e937
                               at /usr/src/rustc-1.63.0/library/core/src/fmt/mod.rs:1197:17
   5:     0x559d42619fd1 - std::io::Write::write_fmt::hdb298d71c7af9b66
                               at /usr/src/rustc-1.63.0/library/std/src/io/mod.rs:1672:15
   6:     0x559d426249fe - std::sys_common::backtrace::_print::h9a164f1073e1bcc5
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:48:5
   7:     0x559d426249fe - std::sys_common::backtrace::print::hb860acc8c631da42
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:35:9
   8:     0x559d426249fe - std::panicking::default_hook::{{closure}}::h2c2be97328f88741
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:295:22
   9:     0x559d42624667 - std::panicking::default_hook::h44f9af4dc0ebff0f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:314:9
  10:     0x559d42624f11 - std::panicking::rust_panic_with_hook::h57071e38e2bc223f
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:698:17
  11:     0x559d42638cd7 - std::panicking::begin_panic_handler::{{closure}}::h7ff3a0ebbf1ba422
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:588:13
  12:     0x559d42638ab4 - std::sys_common::backtrace::__rust_end_short_backtrace::hc8542ca3b5dac53a
                               at /usr/src/rustc-1.63.0/library/std/src/sys_common/backtrace.rs:138:18
  13:     0x559d42624bc2 - rust_begin_unwind
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
  14:     0x559d42614623 - core::panicking::panic_fmt::h11223f0b8c31003a
                               at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
  15:     0x559d426146b3 - core::result::unwrap_failed::h6cd0f84c7b939bcc
                               at /usr/src/rustc-1.63.0/library/core/src/result.rs:1805:5
  16:     0x559d42614b03 - core::result::Result<T,E>::unwrap::h1b920fd338f6f623
  17:     0x559d42614b90 - rust_out::main::_doctest_main_src_matchers_archive_rs_136_0::h2ed878a4952ac666
  18:     0x559d42614b56 - rust_out::main::h557bfc7675621915
  19:     0x559d42614a63 - core::ops::function::FnOnce::call_once::h94ddebef3c641da0
  20:     0x559d426148a9 - std::sys_common::backtrace::__rust_begin_short_backtrace::h4929af86f3e72bb9
  21:     0x559d42614999 - std::rt::lang_start::{{closure}}::hd53acc5a0524aa0f
  22:     0x559d426199d5 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hfb9a2e938981d822
                               at /usr/src/rustc-1.63.0/library/core/src/ops/function.rs:280:13
  23:     0x559d426199d5 - std::panicking::try::do_call::hc4cf7f0440376378
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  24:     0x559d426199d5 - std::panicking::try::h363fd204883b8434
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  25:     0x559d426199d5 - std::panic::catch_unwind::h4bed364cbcdc7f25
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  26:     0x559d426199d5 - std::rt::lang_start_internal::{{closure}}::h250ad398b7b25c83
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:48
  27:     0x559d426199d5 - std::panicking::try::do_call::hc629aaaad685f8fb
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:492:40
  28:     0x559d426199d5 - std::panicking::try::h6d2268af9e37b456
                               at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:456:19
  29:     0x559d426199d5 - std::panic::catch_unwind::ha1c78374531cebdb
                               at /usr/src/rustc-1.63.0/library/std/src/panic.rs:137:14
  30:     0x559d426199d5 - std::rt::lang_start_internal::h2c2e962c94282c61
                               at /usr/src/rustc-1.63.0/library/std/src/rt.rs:128:20
  31:     0x559d42614981 - std::rt::lang_start::h8f1f245c9db3c4ae
  32:     0x559d42614c53 - main
  33:     0x7f11c232c18a - <unknown>
  34:     0x7f11c232c245 - __libc_start_main
  35:     0x559d426147d1 - _start
  36:                0x0 - <unknown>



failures:
    src/lib.rs - get_from_path (line 454)
    src/lib.rs - is_app (line 517)
    src/lib.rs - is_archive (line 528)
    src/lib.rs - is_book (line 553)
    src/lib.rs - is_document (line 565)
    src/lib.rs - is_font (line 577)
    src/lib.rs - is_video (line 601)
    src/matchers/app.rs - matchers::app::is_exe (line 27)
    src/matchers/app.rs - matchers::app::is_wasm (line 5)
    src/matchers/archive.rs - matchers::archive::is_sqlite (line 136)

test result: FAILED. 16 passed; 10 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.16s

error: doctest failed, to rerun pass `--doc`

Does not detect old Office formats

Not sure if that's related to #45 , but my program panicks with thread 'main' panicked at 'assertion failed: sector_id < self.num_sectors', C:\Users\ian\.cargo\registry\src\github.com-1ecc6299db9ec823\cfb-0.4.0\src\internal\sector.rs:65:9 when I try to use infer::get_from_path to read .doc, .ppt and .xls files. I've created the files test.doc, test.xls and test.ppt to test this behavior, and except for test.ppt, they all cause the same error (I've included a different .ppt file which does crash for testing).

I'm using v0.5.0 on Windows 10. The code is based on example/file.rs. Here are the files I used: infer.zip

use std::env::args;
use std::process::exit;

fn main() {
    let path = "path\\to\\test.doc";

    match infer::get_from_path(path) {
        Ok(Some(info)) => {
            println!("Through the arcane magic of this crate we determined the file type to be");
            println!("mime type: {}", info.mime_type());
            println!("extension: {}", info.extension());
        }
        Ok(None) => {
            eprintln!("Unknown file type ๐Ÿ˜ž");
            eprintln!("If you think infer should be able to recognize this file type open an issue on GitHub!");
            exit(1);
        }
        Err(e) => {
            eprintln!("Looks like something went wrong ๐Ÿ˜”");
            eprintln!("{}", e);
            exit(1);
        }
    }
}

SVG finder

A lot of SVG files starts with <svg , so it could should be quite easy to find

Assess Deny of Service risk and potentially limit the buffer size

Initially discussed in #21, stripping of data (such white spaces) at the beginning of input buffer can lead to a Denial Of Service for inputs with a very large amount of data to be stripped before reaching the content to be actually sniffed.

Shall we:

  1. Ignore this issue because we believe there is no such risk.
  2. Let the caller be responsible for this. In such case we should comment this at crate level.
  3. Restrict the size of the buffer globally?
  4. Restrict the size of the buffer for matchers expose to this risk?

Support Opus

Let's add support for Opus!

I don't have any substantial knowledge on the matter, but afaik all Opus-encoded files are packed in Ogg containers. Correct me if I am wrong, but according to Ogg and Opus specifications, the matching function for an Ogg Opus buffer should look something like

pub fn is_oggopus(buf: &[u8]) -> bool {
    buf.len() > 35
        // Ogg
        && buf[0] == 0x4F
        && buf[1] == 0x67
        && buf[2] == 0x67
        && buf[3] == 0x53
        // Opus
        && buf[28] == 0x4F
        && buf[29] == 0x70
        && buf[30] == 0x75
        && buf[31] == 0x73
        && buf[32] == 0x48
        && buf[33] == 0x65
        && buf[34] == 0x61
        && buf[35] == 0x64
}

Unable to infer LZMA files

I have these files which are LZMA type as shown in extension and by 7z archiver

image

image

But when used in this code:

#[derive(Debug)]
pub enum FileKind {
    ZipArchive,
    SevenZipArchive,
    TarArchive,
    GZipArchive,
    LZMAArchive,
    LZHArchive,
    Other,
}

impl FileKind {
    pub fn infer(path: &PathBuf) -> Self {
        println!("{:?}", path);

        let kind = infer::get_from_path(path).unwrap();
        println!("{:?}", kind);

        match kind {
            Some(k) => match k.mime_type() {
                "application/zip" => Self::ZipArchive,
                "application/x-7z-compressed" => Self::SevenZipArchive,
                "application/x-tar" => Self::TarArchive,
                "application/gzip" => Self::GZipArchive,
                "application/x-xz" => Self::LZMAArchive,
                "application/x-lzip" => Self::LZMAArchive,
                _ => Self::Other,
            },
            None => Self::Other,
        }
    }
}

It gives output:

warning: `scoopie` (bin "scoopie") generated 7 warnings (run `cargo fix --bin "scoopie"` to apply 5 suggestions)
    Finished dev [unoptimized + debuginfo] target(s) in 3.82s
     Running `target\debug\scoopie.exe install coreutils`
Commands { cmd: Install(InstallCommand { app: Some("coreutils"), download_only: false, sync: false, update_all: false }) }
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_msys-core_msys-1.0.13-2_msysCORE-1.0.13-2-msys-1.0.13-bin.tar.lzma"
None
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_gettext_gettext-0.17-2_libintl-0.17-2-msys-dll-8.tar.lzma"
None
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_libiconv_libiconv-1.13.1-2_libiconv-1.13.1-2-msys-1.0.13-dll-2.tar.lzma"
None
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_termcap_termcap-0.20050421_1-2_libtermcap-0.20050421_1-2-msys-1.0.13-dll-0.tar.lzma"
None
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_coreutils_coreutils-5.97-3_coreutils-5.97-3-msys-1.0.13-bin.tar.lzma"
None
"C:\\Users\\Rahul\\scoopie\\cache\\coreutils#5.97.3#https_downloads.sourceforge.net_project_mingw_MSYS_Base_coreutils_coreutils-5.97-3_coreutils-5.97-3-msys.RELEASE_NOTES.txt"
None
Ok(())

As if I am doing something wrong or anything else? One more thing is that how to infer LZH archives?

[FEATURE] Get Mime from URL

As title. We want to be able to set mime type for users on a could service without having to download 100gb files. It's possible with Node mime.

JXL support

It would be nice if infer supported JPEG XL files.

At least according to wikipedia, the magic number for .jxl files is FF 0A or 00 00 00 0C 4A 58 4C 20 0D 0A 87 0A.

Thank you!

Doesn't detect all valid docx correctly

I was testing this out with some file types I need to detect, and this (apparently valid?) docx file doesn't appear to be detected properly:
test.docx

I'll take a stab at a patch, but I'm still learning rust.

Better handling of unix file types

I'm going to refer to file (https://www.darwinsys.com/file/) as a reference.
See also: https://en.wikipedia.org/wiki/File_(command)#Specification

I'm using infer like this:

infer::get_from_path(path_to_a_file);

Issues

  1. Directories produce an error, whereas file reports inode/directory.

  2. For other special unix files, file reports inode/chardevice, inode/fifo, etc.

  3. Infer is blocking/waiting, when get_from_path is called with the path to a special file, like a fifo, or /dev/tty.

Doctest failed in fedora packaging

The failed test seem to be because of missing file.
https://download.copr.fedorainfracloud.org/results/remilauzier/infer/fedora-rawhide-x86_64/03495386-rust-infer/builder-live.log.gz

failures:

---- src/lib.rs - get_from_path (line 453) stdout ----
Test executable failed (exit code 101).

stderr:
thread 'main' panicked at 'file read successfully: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:5:6
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Test data not included in crate

The testdata directory is explicitly excluded from the published crate. This means that tests fail when using crates.io as a source (for packaging on Linux distros for example). Is there a reason for this? I can see that the crate would get bigger this way, but right now it is not really having everything needed.

infer::get for R: Read

Currently infer just seems to offer infer::get for a buffer of bytes and infer::get_from_path for a path. However, the crates I am working with generally accept a R: Read or R: Read + Seek type, such that you can pass in a std::io::Cursor or std::io::File or really anything that just implements Read and perhaps Seek.

Another problem is that infer::get either assumes the user has the full byte buffer available or somehow knows the worst-case number of bytes required. The first option is not always feasible, for instance, in my particular use case I am working with archives which can easily end up being several hundreds of megabytes or even gigabytes.

I think it would be nice to have a function that accepts a R: Read, such that it can take as many bytes as it needs to figure out what the file type is. However, for this to work efficiently, it would probably be best to construct some sort of finite state machine from the known byte patterns that takes bytes until it knows what the actual file type is, such that for a ZIP archive it would only need to read 3 bytes and for a tarball it would need to read 261 bytes. Alternatively, you can sort the patterns by length and try each of them in ascending order to achieve the same.

What were the semver breaking changes `0.13` -> `0.14`?

Hello, thanks for your work on this crate. I noticed you published a new version and came to see what the break was and how/if I needed to adapt to that change downstream.

I can't see any breaking changes in https://github.com/bojand/infer/releases/tag/v0.14.0 though. How come this was published as a breaking semver bump?

If a change has no breaking changes it can make life a bit easier downstream (ie for me) by publishing as a non-breaking semver bump.

How far should Infer support file extensions ?

This issue is following discussion started in #21 code review.

Infer has limited support for file extensions. Other crates address file extension conversion from/to mime type, but I feel frustrated with all of them. Let's clarify wether my concerns could/should be addressed by Infer or in another crate.

User story

I am building web applications which serves some files on the file system or proxied from other network locations. I want to set the Content-Type header which drives the web browser behavior in some contexts.

I am also using the mime-type to build URL's with file extensions. I am using mime_guess for this task.

Video and image mime types can be detected by Infer but many text types cannot: Javascript, CSS in particular. My algorithm is to detect file content with Infer first, fallback to mime_guess when I know the file extension second, and default to "application/octet-stream" when no match found.

Concerns

  1. Data source consistency: Infer uses its own hard coded data source. mime-db and mime_guess share the same data source from jshttp/mime-db, but there is no versioning of the DB: their might be some different behaviors across compilations. Also for a given mime type Infer results may be different from mime_guess results. The official source of media types is IANA
  2. API consistency: Infer and mime_db works with &'static str while mime_guess works with MIME from the mime crate as well as a custom MimeGuess type. Using Infer with mime_guess is thus not much convenient: you need boilerplate to convert MIME to &str and back.
  3. Type aliases: neither Infer, mime_guess or mime_db support type aliases. For instance text/javascript is a type alias of application/javascript: Infer results to is_mime_supported should be true in both cases.
  4. Extension aliases: Infer does not support extension aliases, while mime_db and mime_guess do.
  5. DB Overloading: Infer allows to have custom types, and even overloading the default ones (since #13), while mime-db and mime_guess does not.
  6. no_std, no_alloc: Infer allows for no_std, no_alloc since #18, while mime-db and mime_guess does not.
  7. maintenance status: Infer is maintained, so is mime-db, but mime_guess does not seem to be maintained anymore.
  8. build system: mime_db has a build script which has network dependency, while Infer and mime_guess can be built offline.

All this make it difficult for Infer to work hand in hand with either mime-db or mime_guess.

Options

  1. Improve mime_guess but the maintainer does not answer to pull requests. I am abandoning this option for now.
  2. Improve mime-db. I will eventually study this option once we clarified on 1. and 3.
  3. Address all points above within Infer, which is what I want to discuss here.
  4. Write another crate wrapping Infer and mime-db or be a complete rewrite of all. I will consider this if 1, 2 or 3 fail.

Option 2 - Improving mime-db

We could improve mime-db at a point where Infer would remove its current limited support for file extensions and advert to use mime-db instead. We could adjust both crates API so that they work hand-in-hand.

Option 3 - Merging mime_guess and mime_db into Infer.

As per my user story above having a single crate to guess a mime type from either content or file extension makes sens. Such ideal crate would have the following features:

  • no_alloc, no_std.
  • A static DB built from IANA and versioned outside of the build script.
  • Allow overloading the default DB at runtime (and eventually at compile time too).
  • Handle type and extension aliases.

@abonander, @viz-rs you are welcome to join the discussion!

Invalid Java class file magic byte?

I was running infer over some Java class files and wasn't getting a hit as Java, but instead as application/x-mach-binary. Setting aside the collision of magic byte with Mach-O's definition aside for the moment, I'm not sure where the Java magic byte is coming from?

According to the spec Java class files start with 0xCAFEBABE. I tried looking into the history of where Infer's current Java magic byte came from but it looks like it has been there since the initial commit to this repo and there didn't seem any more context nor other open issues.

This does mean a possible corrected Java matcher would collide with Mach-O's matcher.

@bojand I'd be happy to put up a PR to fix both issues if there's appetite for it. This comment in the Mach-O matcher is already referencing a post detailing how libmagic gets around this magic byte collision.

After the common magic byte, Java devotes 2 bytes to a minor version and then 2 bytes to a major version of the class file. Major versions start at 45, versions less than 45 are pre Java 1.1 and presumed from its pre-historic Oak period.

Mach-O devotes the full 4 bytes to specifying the number of multi-arch entries in the "fat" file. There's 18 defined archetypes, AFAIK, that a Mach-O archive could contain to at this time.

Given new widespread CPU architectures are few and far between nowadays the comment from libmagic seems like a reasonable "hack" here to discriminate between the two:

  1. Load in the 4 bytes after a matched magic byte of 0xCAFEBABE.
  2. If the 4 bytes are less than 45, then it's Mach-O (should be fine until an additional 27 new CPU architectures are added to Mach-O).
  3. If the number is greater than 45 then it's a Java class file.
  • For extra due diligence, because the minor version is the 2 bytes before the major version's 2 bytes, that would give a radically large number if viewed as a single 4 byte value. Once it's confirmed the whole 4 bytes are > 45, we should parse down to just the latter 2 bytes and confirm just those 2 bytes are greater than 45.

Fwiw it seemed like Infer was also lacking a Java class file test case, so I'd add that for extra confirmation in my PR. It looks like it already has some Mach-O samples for testing.

Method get_from_path can be really expensive.

I noticed how memory usage drastically increased when using method get_from_path with really large files, the reason is obvious, fs::read loads the entire file on memory.

This method should be deprecated or replaced with a new one, since it can leverage to undesired side effects that can be hard to debug.

My replacement proposal for this method is the following:

pub fn get_from_path<P: AsRef<Path>>(&self, path: P, hints: Option<Vec<Mime>>) -> Result<Option<Type>, std::io::Error>;
  • Mime is an enum with all supported file types, and a method to get the minimum amount of bytes to infer that type (needed bytes).
  • hints could be a list of the expected mime types, with these value get_from_path would be
    able to read only the needed amount of bytes (will pick the maximum amount).
  • If hints is None, get_from_path will read the maximum needed bytes across all the variants of Mime.

Does not correctly detect plain text

I expect this is because a file produced by echo "hello world!" >> /tmp/hello_world.txt doesn't have a MIME type, but is there any way to handle this?

Not detecting .7z file

The tool states that it supports .7z but I am testing with a .7z and it says:
Unknown file type.

Please assist. Thank you

How many header bytes are needed form image id?

Tried to figure it out by myself, but seems to be that docs could be misleading so I preferred to ask, given that:

  1. The original Go repo says only the initial 262 bytes of a max header size are needed
  2. The examples show a buffer with just 4 bytes and works for images
  3. In our tests 8 bytes are good enough, obviously if 4 bytes work.

The real question is for png and jpg how many bytes are actually required to be "sliced"?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.