#[non_exhaustive]pub struct MagicDatabase { /* private fields */ }Expand description
Main interface for magic rule database
Implementations§
Source§impl MagicDatabase
impl MagicDatabase
Sourcepub fn with_builtin_rules() -> Result<Self>
pub fn with_builtin_rules() -> Result<Self>
Create a database using built-in magic rules.
Loads magic rules that are compiled into the library binary at build time
from src/builtin_rules.magic. These rules provide high-confidence detection
for common file types including executables (ELF, PE/DOS), archives (ZIP, TAR,
GZIP), images (JPEG, PNG, GIF, BMP), and documents (PDF).
§Security
This constructor uses EvaluationConfig::default(), which leaves
timeout_ms unset (unbounded). When processing untrusted input
(adversarial file buffers, large uploads, etc.), prefer
MagicDatabase::with_builtin_rules_and_config with
EvaluationConfig::performance() (which sets a 1-second timeout)
or construct a config explicitly with a non-None timeout sized
for your workload. The Default impl intentionally targets CLI
one-shot usage rather than long-running services.
§Thread safety
MagicDatabase is Send + Sync and holds no interior mutability,
so an Arc<MagicDatabase> can be shared across threads for
parallel file scanning. A fresh evaluation context is constructed
per evaluate_buffer / evaluate_file call, so concurrent calls
do not interfere.
§Errors
Currently always returns Ok. In future implementations, this may return
an error if the built-in rules fail to load or validate.
§Examples
use libmagic_rs::MagicDatabase;
let db = MagicDatabase::with_builtin_rules()?;
let result = db.evaluate_buffer(b"\x7fELF")?;
// Returns actual file type detection (e.g., "ELF")Sourcepub fn with_builtin_rules_and_config(config: EvaluationConfig) -> Result<Self>
pub fn with_builtin_rules_and_config(config: EvaluationConfig) -> Result<Self>
Create database with built-in rules and custom configuration.
Loads built-in magic rules compiled at build time and applies the specified evaluation configuration (e.g., custom timeout settings).
§Security
For untrusted input (adversarial file buffers, web uploads, mail
scanning), pass a config with an explicit timeout such as
EvaluationConfig::performance(). The default config has
timeout_ms = None which leaves evaluation unbounded; see the
rationale on EvaluationConfig::default.
§Arguments
config- Custom evaluation configuration to use with the built-in rules
§Errors
Returns LibmagicError if the configuration is invalid (e.g., timeout is zero).
§Examples
use libmagic_rs::{MagicDatabase, EvaluationConfig};
// Prefer the performance() preset over default() when processing
// untrusted input. default() has no timeout by design.
let config = EvaluationConfig::performance();
let db = MagicDatabase::with_builtin_rules_and_config(config)?;Sourcepub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self>
Load magic rules from a file
§Security
This constructor uses EvaluationConfig::default(), which
leaves timeout_ms unset. See the security note on
Self::with_builtin_rules for the implications and prefer
Self::load_from_file_with_config with an explicit timeout
when processing untrusted input.
§Arguments
path- Path to the magic file to load
§Errors
Returns LibmagicError::IoError if the file cannot be read.
Returns LibmagicError::ParseError if the magic file format is invalid.
§Examples
use libmagic_rs::MagicDatabase;
let db = MagicDatabase::load_from_file("magic.db")?;Sourcepub fn load_from_file_with_config<P: AsRef<Path>>(
path: P,
config: EvaluationConfig,
) -> Result<Self>
pub fn load_from_file_with_config<P: AsRef<Path>>( path: P, config: EvaluationConfig, ) -> Result<Self>
Load from file with custom config (e.g., timeout).
§Security
For untrusted input, pass EvaluationConfig::performance() or
a config with an explicit non-None timeout_ms. See
Self::with_builtin_rules for the full rationale.
§Errors
Returns error if file cannot be read, parsed, or config is invalid
Sourcepub fn load_from_bytes(bytes: Vec<u8>) -> Result<Self>
pub fn load_from_bytes(bytes: Vec<u8>) -> Result<Self>
Load text magic rules from owned bytes.
This consumes the supplied Vec<u8> and reuses its allocation when
the input is valid UTF-8, avoiding the additional full-buffer copy made
when loading already-buffered data through Self::load_from_reader.
Invalid UTF-8 is replaced as documented for file and reader loading and
may require another allocation. Input is bounded by the same 1 GiB limit
as Self::load_from_file. Compiled binary .mgc databases are not
supported.
Databases loaded from bytes have no filesystem source, so
Self::source_path returns None.
§Parsing behavior
Parsing is tolerant, matching Self::load_from_file: a rule line
that fails to parse is skipped along with its indented subtree, and a
warning is logged rather than returned. Input in which every line fails
to parse therefore yields an Ok database with no rules, not an error.
§Security
This constructor uses EvaluationConfig::default(), which leaves
timeout_ms unset. See the security note on
Self::with_builtin_rules and prefer
Self::load_from_bytes_with_config with an explicit timeout when
processing untrusted input.
§Errors
Returns LibmagicError::ParseError if the input is oversized,
compiled .mgc data, or cannot be parsed as a text magic database.
§Examples
use libmagic_rs::MagicDatabase;
let rules = b"0 string INKMEM in-memory magic\n".to_vec();
let db = MagicDatabase::load_from_bytes(rules)?;
let result = db.evaluate_buffer(b"INKMEM payload")?;
assert!(result.description.contains("in-memory magic"));Sourcepub fn load_from_bytes_with_config(
bytes: Vec<u8>,
config: EvaluationConfig,
) -> Result<Self>
pub fn load_from_bytes_with_config( bytes: Vec<u8>, config: EvaluationConfig, ) -> Result<Self>
Load text magic rules from owned bytes with custom evaluation config.
See Self::load_from_bytes for ownership, size limits, and
source-path behavior.
§Security
For untrusted input, pass EvaluationConfig::performance() or a
config with an explicit non-None timeout_ms.
§Errors
Returns an error if the config is invalid or the input is oversized,
compiled .mgc data, or cannot be parsed as a text magic database.
§Examples
use libmagic_rs::{EvaluationConfig, MagicDatabase};
let rules = b"0 string INKMEM in-memory magic\n".to_vec();
let config = EvaluationConfig::performance();
let db = MagicDatabase::load_from_bytes_with_config(rules, config)?;
let result = db.evaluate_buffer(b"INKMEM payload")?;
assert!(result.description.contains("in-memory magic"));Sourcepub fn load_from_reader<R: Read>(reader: R) -> Result<Self>
pub fn load_from_reader<R: Read>(reader: R) -> Result<Self>
Load text magic rules from a reader.
This accepts any Read implementation, including byte slices,
std::io::Cursor, files, and buffered readers. Input is bounded by
the same 1 GiB limit as Self::load_from_file. Compiled binary
.mgc databases are not supported.
Databases loaded from a reader have no filesystem source, so
Self::source_path returns None.
§Parsing behavior
Parsing is tolerant, matching Self::load_from_file: a rule line
that fails to parse is skipped along with its indented subtree, and a
warning is logged rather than returned. Input in which every line fails
to parse therefore yields an Ok database with no rules, not an error.
The reader is drained until it reports end of input. A stream that ends early – a reset socket, a truncated pipe – is indistinguishable from a short magic database, so it loads successfully with only the rules that arrived. Callers that need completeness guarantees must enforce them on the stream before calling this method.
§Security
This constructor uses EvaluationConfig::default(), which leaves
timeout_ms unset. See the security note on
Self::with_builtin_rules and prefer
Self::load_from_reader_with_config with an explicit timeout when
processing untrusted input.
Note that timeout_ms bounds rule evaluation, not this read. The
reader is capped in size, but not in time: a reader that blocks or
trickles bytes without reaching end of input stalls this call. Apply
your own read timeout or deadline before passing in a stream you do
not control.
§Errors
Returns LibmagicError::IoError if the reader fails, or
LibmagicError::ParseError if the input is oversized, compiled
.mgc data, or cannot be parsed as a text magic database.
§Examples
use libmagic_rs::MagicDatabase;
let rules = b"0 string INKMEM in-memory magic\n";
let db = MagicDatabase::load_from_reader(rules.as_slice())?;
let result = db.evaluate_buffer(b"INKMEM payload")?;
assert!(result.description.contains("in-memory magic"));Sourcepub fn load_from_reader_with_config<R: Read>(
reader: R,
config: EvaluationConfig,
) -> Result<Self>
pub fn load_from_reader_with_config<R: Read>( reader: R, config: EvaluationConfig, ) -> Result<Self>
Load text magic rules from a reader with custom evaluation config.
See Self::load_from_reader for supported inputs, size limits, and
source-path behavior.
§Security
For untrusted input, pass EvaluationConfig::performance() or a
config with an explicit non-None timeout_ms.
§Errors
Returns an error if the config is invalid, the reader fails, or the
input is oversized, compiled .mgc data, or cannot be parsed as a text
magic database.
§Examples
use libmagic_rs::{EvaluationConfig, MagicDatabase};
let rules = b"0 string INKMEM in-memory magic\n";
let config = EvaluationConfig::performance();
let db = MagicDatabase::load_from_reader_with_config(rules.as_slice(), config)?;
let result = db.evaluate_buffer(b"INKMEM payload")?;
assert!(result.description.contains("in-memory magic"));Sourcepub fn evaluate_file<P: AsRef<Path>>(&self, path: P) -> Result<EvaluationResult>
pub fn evaluate_file<P: AsRef<Path>>(&self, path: P) -> Result<EvaluationResult>
Evaluate magic rules against a file
§Arguments
path- Path to the file to evaluate
§Errors
Returns LibmagicError::IoError if the file cannot be accessed.
Returns LibmagicError::EvaluationError if rule evaluation fails.
§Security
This method has a time-of-check/time-of-use (TOCTOU) window between
resolving the path and memory-mapping the file
(CWE-367).
Internally, evaluate_file first calls std::fs::metadata(path) to
detect the empty-file case, then opens and memory-maps the file via
io::FileBuffer::new, which itself re-validates file metadata
(regular file, size bounds) before calling create_memory_mapping.
Between these validation steps and the final mmap call, the path
may be swapped (for example, via a symlink replacement or rename)
by another process. The content that gets mapped may therefore
differ from the file that passed validation.
The I/O layer mitigates the common shapes of this attack by
canonicalizing the path and rejecting special file types, and the
mapping itself is read-only, so a successful exploit cannot corrupt
the victim file. The residual risk is that evaluate_file may
classify a different file than the caller intended.
For adversarial or untrusted environments, prefer
MagicDatabase::evaluate_buffer: load the bytes yourself using
whatever resource-bounded, TOCTOU-aware I/O strategy your
application requires (e.g., openat with O_NOFOLLOW, holding an
open file descriptor across validation and read), then pass the
in-memory slice directly to evaluate_buffer. See
the security assurance case
for the residual-risk discussion.
§Examples
use libmagic_rs::MagicDatabase;
let db = MagicDatabase::load_from_file("magic.db")?;
let result = db.evaluate_file("sample.bin")?;
println!("File type: {}", result.description);Sourcepub fn evaluate_buffer(&self, buffer: &[u8]) -> Result<EvaluationResult>
pub fn evaluate_buffer(&self, buffer: &[u8]) -> Result<EvaluationResult>
Evaluate magic rules against an in-memory buffer
This method evaluates a byte buffer directly without reading from disk, which is useful for stdin input or pre-loaded data.
§Arguments
buffer- Byte buffer to evaluate
§Errors
Returns LibmagicError::EvaluationError if rule evaluation fails.
§Examples
use libmagic_rs::MagicDatabase;
let db = MagicDatabase::load_from_file("/usr/share/misc/magic")?;
let buffer = b"test data";
let result = db.evaluate_buffer(buffer)?;
println!("Buffer type: {}", result.description);Sourcepub fn config(&self) -> &EvaluationConfig
pub fn config(&self) -> &EvaluationConfig
Returns the evaluation configuration used by this database.
This provides read-only access to the evaluation configuration for callers that need to inspect resource limits or evaluation options.
Sourcepub fn source_path(&self) -> Option<&Path>
pub fn source_path(&self) -> Option<&Path>
Returns the path from which magic rules were loaded.
This method returns the source path that was used to load the magic rules into this database. It is useful for debugging, logging, and tracking the origin of magic rules.
§Returns
Some(&Path)- If the database was loaded from a file or directory usingload_from_file()None- If the database was constructed programmatically or the source path was not recorded
§Examples
use libmagic_rs::MagicDatabase;
let db = MagicDatabase::load_from_file("/usr/share/misc/magic")?;
if let Some(path) = db.source_path() {
println!("Rules loaded from: {}", path.display());
}