libmagic clib File Detection

File type detection by magic bytes. Identifies files by their content, not by extension — the library behind the Unix file command.

Version1.0.0
Typeclib
Requireslibmagic-dev
ppm install libmagic

What is libmagic?

libmagic is the library behind the Unix file command. It identifies files by inspecting their magic bytes — byte patterns at specific offsets in the file content — rather than trusting the file extension or any user-supplied metadata.

libmagic ships with a database of over 1,000 patterns covering virtually every common file format: images, documents, archives, executables, audio, video, and more. When you call it on a file it reads the first bytes, matches them against the database rules, and returns either a human-readable description or a MIME type string.

Why content-based detection matters

A file named image.png renamed to image.txt still returns image/png — the bytes do not lie. This protects upload endpoints that rely on file extensions or Content-Type headers, both of which are fully user-controlled. Validate what the file actually is before processing it.

Example Identifications

File typeMIME typeDescription string
JPEG imageimage/jpegJPEG image data, JFIF standard 1.01
PDF documentapplication/pdfPDF document, version 1.7
ZIP archiveapplication/zipZip archive data, at least v2.0 to extract
ELF binaryapplication/x-executableELF 64-bit LSB executable, x86-64
Shell scripttext/x-shellscriptPOSIX shell script, ASCII text executable
UTF-8 texttext/plain; charset=utf-8UTF-8 Unicode text
Empty fileinode/x-emptyempty

Flag Modes

Flags control what information libmagic returns. Pass them to Open() or change them later with SetFlags().

FlagDescription
mfNoneHuman-readable description string (default mode)
mfMimeTypeReturn only the MIME type, e.g. image/jpeg
mfMimeReturn MIME type plus charset, e.g. text/plain; charset=utf-8
mfMimeEncodingReturn character encoding only, e.g. utf-8, binary
mfCompressPeek inside compressed files (.gz, .bz2) and identify the inner content
mfSymlinkFollow symbolic links to the target file
mfDevicesLook at device files
mfContinueReturn all matches, not just the best one
mfNoCheckCompressDo not decompress; identify the outer container only

Types

TMagicHandle

An opaque integer handle representing an open libmagic context (the magic cookie). Obtain one with Open, OpenMIME, or OpenDesc; release it with Close. Each thread should use its own handle.

TMagicFlags

type
  TMagicFlags = (
    mfNone             = $0000000,  { human-readable description }
    mfDebug            = $0000001,  { print debug info }
    mfSymlink          = $0000002,  { follow symlinks }
    mfCompress         = $0000004,  { check inside compressed files }
    mfDevices          = $0000008,  { look at device files }
    mfMimeType         = $0000010,  { return MIME type }
    mfContinue         = $0000020,  { return all matches }
    mfCheck            = $0000040,  { validate magic database }
    mfPreserveAtime    = $0000080,  { restore file atime after read }
    mfRaw              = $0000100,  { don't translate unprintable chars }
    mfError            = $0000200,  { return error for unknown files }
    mfMimeEncoding     = $0000400,  { return MIME encoding }
    mfMime             = $0000410,  { MIME type + encoding }
    mfApple            = $0000800,  { return Apple creator/type }
    mfExtension        = $1000000,  { return file extension list }
    mfNoCheckCompress  = $0001000,  { don't decompress }
    mfNoCheckELF       = $0010000,  { don't check ELF details }
    mfNoCheckText      = $0020000,  { don't check text files }
    mfNoCheckCDF       = $0040000,  { don't check CDF (MS Office) }
    mfNoCheckCSV       = $0080000   { don't check CSV }
  );

API Reference

Open / Close

FunctionDescription
Open(Flags, MagicFile)Open a magic context with the given flags. Pass an empty string for MagicFile to use the system database.
OpenMIMEOpen with mfMimeType mode. Most common for web and upload validation.
OpenDescOpen with description mode (human-readable output).
Close(M)Close the handle and free all associated resources.

Detection

FunctionDescription
IdentifyFile(M, Path)Identify a file by path. Returns MIME type or description depending on the flags set on M.
IdentifyBuffer(M, Data)Identify from an in-memory string buffer. No file needed — useful for stream data.

One-shot Convenience

These functions open and close a handle internally. Convenient for single calls; for multiple files use an open handle instead.

FunctionDescription
GetMIMEType(Path)Return the MIME type of a file.
GetDescription(Path)Return the human-readable description of a file.
GetMIMETypeFromBuffer(Data)Return the MIME type detected from an in-memory buffer.
GetEncoding(Path)Return the character encoding (e.g. utf-8, iso-8859-1, binary).

Type Helpers

FunctionDescription
IsMIMEType(Path, MIMEType)Return True if the file matches the given MIME type exactly.
IsImage(Path)Return True if the MIME type starts with image/.
IsText(Path)Return True if the MIME type starts with text/.
IsPDF(Path)Return True if the file is application/pdf.
IsArchive(Path)Return True if the file is a ZIP, TAR, GZ, or other archive format.
IsExecutable(Path)Return True if the file is an ELF, PE, or Mach-O executable.

Database

ProcedureDescription
LoadDatabase(M, Path)Load a custom magic database file into the handle, replacing the default.
CompileDatabase(SourcePath, OutputPath)Compile a text-format magic rules file into a binary database.

Flags & Error

FunctionDescription
SetFlags(M, Flags)Change the flags on an already-open handle.
GetError(M)Return the last error message for the handle, or an empty string if none.

Code Example — Validate File Uploads

uses libmagic;
var
  MIME: string;
  AllowedTypes: array of string;
begin
  { One-shot MIME detection }
  MIME := GetMIMEType('/uploads/user_file.jpg');
  WriteLn('Detected: ', MIME);  { image/jpeg }

  { Validate upload }
  if not IsImage('/uploads/user_file.jpg') then begin
    WriteLn('Rejected: not an image');
    Exit;
  end;

  { Check specific types }
  if IsPDF('/uploads/document') then
    WriteLn('Processing PDF...');

  { Use open handle for multiple files (more efficient) }
  var M := OpenMIME;
  WriteLn(IdentifyFile(M, 'data.bin'));    { detect binary }
  WriteLn(IdentifyBuffer(M, #$89'PNG'));   { PNG magic bytes }
  Close(M);
end.
Security note

Always validate uploaded files by their content, not by the file extension or Content-Type header. Both are fully user-controlled and trivially spoofed. libmagic reads the actual bytes, making it the correct tool for enforcing file type policies at upload endpoints.

Install

ppm install libmagic
Version1.0.0
Typeclib
Requireslibmagic-dev
PlatformLinux / macOS

About

Powers the Unix file command. Database of 1,000+ patterns for identifying file formats by magic bytes.

API

  • Open(Flags, MagicFile)
  • OpenMIME
  • OpenDesc
  • Close(M)
  • IdentifyFile(M, Path)
  • IdentifyBuffer(M, Data)
  • GetMIMEType(Path)
  • GetDescription(Path)
  • GetMIMETypeFromBuffer(Data)
  • GetEncoding(Path)
  • IsMIMEType(Path, Type)
  • IsImage(Path)
  • IsText(Path)
  • IsPDF(Path)
  • IsArchive(Path)
  • IsExecutable(Path)
  • LoadDatabase(M, Path)
  • CompileDatabase(Src, Out)
  • SetFlags(M, Flags)
  • GetError(M)
Thread safety

Each thread should open its own TMagicHandle with OpenMIME or Open. Handles are not thread-safe to share.