Marcel 2.0.0 modernizes the toolchain, hardens the release pipeline, and teaches the content sniffer several new families of formats. It is a major release because it drops old Rubies and changes the canonical type returned for some inputs — details below so you can scan for the ones that affect you.
Breaking changes
- Ruby 3.3 or newer is required (was 2.3). (#170)
- Canonical type changes — the same bytes or filename may now return a different (more standard) type:
- Aliased types now resolve to their canonical form on output (#171):
audio/x-aac→audio/aac,audio/x-flac→audio/flac,audio/vnd.wave→audio/x-wav,text/x-yaml→application/yaml,application/x-debian-package→application/vnd.debian.binary-package,application/x-xliff+xml→application/xliff+xml. Lookups by any alias still work. image/bmp;format=compressedis now plainimage/bmp(#148)..cr2files areimage/x-canon-cr2instead ofimage/x-raw-canon(#172).- OpenXPS (
.oxps) is split from XPS (#171). - The XML/HTML detection work below can relabel documents that previously fell back to
application/xml,text/html, orapplication/octet-stream.
- Aliased types now resolve to their canonical form on output (#171):
Security & hardening
A review of the detection pipeline landed as a series of PRs (#157–#164):
- MIME data is validated before table generation, and the generated tables are checked in CI (#157,
rake tables:check). - HTML and XHTML magic matches only bounded opening-tag patterns instead of unanchored scans (#158).
- IO edge cases — partial reads, unseekable and unrewindable IOs, non-string input — are handled explicitly while sniffing (#159).
- Declared MIME types are validated rather than trusted (#160).
- Marcel's detection boundary — what sniffing does and does not promise — is documented in the README (#161).
- CI runs with locked dependencies (#163), and the release workflow builds and publishes the same verified gem artifact with sha256 recorded and sigstore attestation (#164), with the gem's contents verified by script (#162, #173).
New detection
- OOXML documents (
.docx/.xlsx/.pptxand their macro-enabled variants) are identified from the ZIP central directory, regardless of which application produced them (#169). - XML vocabularies are identified by their root element, the way Apache Tika does: RSS, Atom, KML, Apple property lists, XSLT, ONIX, iWork flat XML, Office 2003 XML, and friends (#173 and #175, fixing #48).
- Canon CR2 raw images (#172).
- RAR archives (#155, @tristan-f-r) and Google Sheets shortcuts (#156, @tristan-f-r).
- AVIF image sequences (
avisbrand) (#151, @mm12) and audio-only.m4afiles (#147). - HTML detection also checks the end of the document for closing tags (#146).
Performance
- The common-type fast path is restored with subtype-aware ordering, so common formats like JPEG are identified in ~25 IO reads instead of hundreds, without preempting subtype matchers (#172, #174).
- Sniffing uses
IO#seekwhere possible instead of reading and discarding, including for regexp magic (#144, #145).
Upgrading
Most applications need no changes beyond Ruby ≥ 3.3. If you compare Marcel's output against stored MIME types, re-check the canonical type changes above — lookups by the old aliases still resolve, but Marcel now returns the canonical name.