Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mail Mime Parser Laravel Package

zbateson/mail-mime-parser

A testable, PSR-compliant PHP mail MIME parser for RFC 822/2822/5322 messages. An alternative to imap* functions and Pear libraries, it parses strings, resources, or PSR-7 streams into messages with forgiving, standards-based handling. Requires PHP 8.1+.

View on GitHub
Deep Wiki
Context7
4.0.6

What's Changed

  • Strip control characters from the MIME type, charset, transfer encoding, micalg and protocol arguments of the message-building API, as is already done for attachment filenames -- thanks @manus-pi, @AlpetGexha and @kemrec
  • Add configurable limits on the total number of headers, header bytes and header tokens parsed in a message, each recording a parse error when reached (override via DI config):
    • maxMessageHeaderCount (default 50000) — maximum headers read per message across all parts
    • maxMessageHeaderSizeBytes (default 8388608) — maximum header bytes read per message across all parts
    • maxMessageHeaderTokenCount (default 250000) — maximum header tokens parsed per message across all parts; headers parsed after it is reached are kept as one unparsed token each
  • Read past the rest of a part's headers when a header limit is reached, rather than treating them as the part's content
  • Skip building the error logging context when no logger is configured
  • Lower the default maxMessagePartCount from 10000 to 1000
  • Parse quoted header values in O(n) rather than O(n²) -- thanks @manus-pi
  • Parse address groups and RFC 2231 split parameters in O(n) rather than O(n²)
  • Match multipart boundary lines in constant time regardless of nesting depth
  • Parse each part's Content-Type header once rather than twice
  • Keep only the mime-encoded header parts that recorded decoding errors, rather than every part
  • Strip control characters from uuencoded part filenames and from the remaining message-building helper arguments
  • Treat a multipart part with an attachment disposition as an attachment, and no longer return its children as message content -- thanks @AlpetGexha

Security

This release fixes two reported vulnerabilities:

  • GHSA-gmgm-r6fh-fq6g -- header injection through message-building arguments not covered by the fix for CVE-2026-61815.
  • GHSA-fcgh-j754-jh42 -- uncontrolled resource consumption (CPU/memory) when parsing untrusted messages, not covered by the fixes for CVE-2026-61816 and GHSA-pmx8-5pxm-f2r6.

Reported by @manus-pi, @AlpetGexha and @kemrec; the unbounded per-message header memory was found during the resulting review. Upgrading is recommended.

4.0.2

What's Changed

  • Strip control characters (CR/LF) from attachment filenames and from decoded header parameter and MIME-encoded-word values -- thanks @iliaal
  • Add configurable limits to MIME parsing, each recording a parse error when reached (override via DI config) -- thanks @iliaal:
    • maxMimePartDepth (default 256) — maximum multipart nesting depth
    • maxHeaderCount (default 1000) — maximum headers per part
    • maxHeaderSizeBytes (default 1048576) — maximum total header bytes per part
  • Append child parts in O(n) rather than O(n²) -- thanks @iliaal
  • Generate MIME boundaries with random_bytes() -- thanks @iliaal

Security

This release fixes two privately reported vulnerabilities:

  • GHSA-36h5-qg4p-q2qf -- CRLF header injection via attachment filename.
  • GHSA-f6v3-2qmr-vfjx -- uncontrolled resource consumption (CPU/memory) when parsing untrusted MIME.

Found and reported privately by @iliaal, who also proposed fixes that informed the patches. Upgrading is recommended.

3.0.6

What's Changed

  • Strip control characters (CR/LF) from attachment filenames and from decoded header parameter and MIME-encoded-word values -- thanks @Iliaal
  • Add configurable limits to MIME parsing, each recording a parse error when reached (override via DI config) -- thanks @Iliaal:
    • maxMimePartDepth (default 256) — maximum multipart nesting depth
    • maxHeaderCount (default 1000) — maximum headers per part
    • maxHeaderSizeBytes (default 1048576) — maximum total header bytes per part
  • Append child parts in O(n) rather than O(n²) -- thanks @Iliaal.
  • Generate MIME boundaries with random_bytes() -- thanks @Iliaal.

Security

This release fixes two privately reported vulnerabilities:

  • GHSA-36h5-qg4p-q2qf -- CRLF header injection via attachment filename.
  • GHSA-f6v3-2qmr-vfjx -- uncontrolled resource consumption (CPU/memory) when parsing untrusted MIME.

Found and reported privately by @iliaal, who also proposed fixes that informed the patches. Upgrading is recommended.

3.0.4

What's Changed

New Contributors

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/3.0.3...3.0.4

3.0.3
  • Fix to allow empty address groups #241
  • Ignore ws between rfc2047 parts in q-part #240
  • Fix PartBuilder parent parameter type

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/3.0.2...3.0.3

3.0.2

What's Changed

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/3.0.1...3.0.2

3.0.1

Fixes version constraints for php-di, guzzlehttp/psr7 and phpunit.

2.4.1

What's Changed

3.0.0
  • Logging support, pass in a LoggerInterface to the constructor or call MailMimeParser::setGlobalLogger. Not much is actually logged at this point (please submit pull requests to add useful log messages)

  • ErrorBag class -- most user classes extend ErrorBag which allows classes to keep track of errors by calling addError, and users to call getErrors or getAllErrors (to include errors in child classes).

    Additional validation on objects is not performed, but can be done by passing 'true' as the validate parameter on getErrors/getAllErrors. By default only errors encountered without additional validation are added.

    See IErrorBag class for documentation.

  • If ParserManagerService can't find a parser for a PartBuilder, CompatibleParserNotFoundException will be thrown. This would only happen if customizing the used parsers passed on to ParserManagerService since the default set includes a 'catch-all' with NonMimeParserService.

  • protected AbstractHeader::setParseHeaderValue renamed to parseHeaderValue, and signature changed.

  • Can look up comment parts in headers -- use IHeader::getAllParts to return all parsed parts including comment parts.

  • GenericHeader getValue returns a string value of the combination of all its non-comment parts. This applies to any header that doesn't have a more specialized header type (not an address, date, id, parameter, received or subject header), see HeaderFactory docs for specifics.

  • IHeader now has a getComments() method that returns a string array of comments. ReceivedHeader no longer has protected members $comments and $date ($date is now private -- still has AbstractHeader::getComments(), and ReceivedHeader::getDateTime())

  • Switched to PHP-DI, users can provide a array|string|DefinitionSource to override definitions

    • Renamed service classes to clarify: o AbstractParser -> AbstractParserService o HeaderParser -> HeaderParserService o IParser -> IParserService o MessageParser -> MessageParserService o MimeParser -> MimeParserService o NonMimeParser -> NonMimeParserService o ParserManager -> ParserManagerService o All consumer classes, e.g. AbstractConsumer -> AbstractConsumerService
  • Refactored Header classes to depend on their respective IConsumerService classes they need

  • Refactored ConsumerService classes to define which sub-ConsumerService classes they depend on. Removed ConsumerService.

  • Cleaned up method return types and parameter types.

  • Added an AbstractHeader::from which returns IHeader objects from a passed header line, or header name/value pair. Static method can be called on a sub class which returns its type, for example AddressHeader::from would return an AddressHeader regardless of the name parameter or name of header in the passed line.

  • Refactored HeaderPart classes with the following goals:

    • Token classes to be used by Consumers to convert from a string to a "part".
    • When processing a part, consumer may combine them into a 'ContainerPart' array to return to a header.
    • Non-Token classes are "ContainerParts" and contain other HeaderParts.
    • When constructing a ContainerPart, other HeaderParts can become children of it.
    • HeaderPart is an ErrorBag, so it and all its children can report errors up the chain all the way to Message.

Merged PRs

New Contributors

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/2.4.0...3.0.0

3.0.0-beta.2
  • Added missing tests
  • Added IMessage::getSubject
3.0.0-beta
  • Logging support, pass in a LoggerInterface to the constructor or call MailMimeParser::setGlobalLogger. Not much is actually logged at this point (please submit pull requests to add useful log messages)

  • ErrorBag class -- most user classes extend ErrorBag which allows classes to keep track of errors by calling addError, and users to call getErrors or getAllErrors (to include errors in child classes).

    Additional validation on objects is not performed, but can be done by passing 'true' as the validate parameter on getErrors/getAllErrors. By default only errors encountered without additional validation are added.

    See IErrorBag class for documentation.

  • If ParserManagerService can't find a parser for a PartBuilder, CompatibleParserNotFoundException will be thrown. This would only happen if customizing the used parsers passed on to ParserManagerService since the default set includes a 'catch-all' with NonMimeParserService.

  • protected AbstractHeader::setParseHeaderValue renamed to parseHeaderValue, and signature changed.

  • Can look up comment parts in headers -- use IHeader::getAllParts to return all parsed parts including comment parts.

  • GenericHeader getValue returns a string value of the combination of all its non-comment parts. This applies to any header that doesn't have a more specialized header type (not an address, date, id, parameter, received or subject header), see HeaderFactory docs for specifics.

  • IHeader now has a getComments() method that returns a string array of comments. ReceivedHeader no longer has protected members $comments and $date ($date is now private -- still has AbstractHeader::getComments(), and ReceivedHeader::getDateTime())

  • Switched to PHP-DI, users can provide a array|string|DefinitionSource to override definitions

    • Renamed service classes to clarify: o AbstractParser -> AbstractParserService o HeaderParser -> HeaderParserService o IParser -> IParserService o MessageParser -> MessageParserService o MimeParser -> MimeParserService o NonMimeParser -> NonMimeParserService o ParserManager -> ParserManagerService o All consumer classes, e.g. AbstractConsumer -> AbstractConsumerService
  • Refactored Header classes to depend on their respective IConsumerService classes they need

  • Refactored ConsumerService classes to define which sub-ConsumerService classes they depend on. Removed ConsumerService.

  • Cleaned up method return types and parameter types.

  • Added an AbstractHeader::from which returns IHeader objects from a passed header line, or header name/value pair. Static method can be called on a sub class which returns its type, for example AddressHeader::from would return an AddressHeader regardless of the name parameter or name of header in the passed line.

  • Refactored HeaderPart classes with the following goals:

    • Token classes to be used by Consumers to convert from a string to a "part".
    • When processing a part, consumer may combine them into a 'ContainerPart' array to return to a header.
    • Non-Token classes are "ContainerParts" and contain other HeaderParts.
    • When constructing a ContainerPart, other HeaderParts can become children of it.
    • HeaderPart is an ErrorBag, so it and all its children can report errors up the chain all the way to Message.
2.3.0

What's Changed

New Contributors

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/2.2.3...2.3.0

Huge thank you to @phpfui for this release and migration to php 7.1+.

2.2.3

What's Changed

New Contributors

Full Changelog: https://github.com/zbateson/mail-mime-parser/compare/2.2.2...2.2.3

2.2.2

#189 fixes a documentation error thanks to @naitsirch #197 Fix PHP 8.1 return type deprecation notices. @alexei-bykovski

2.2.1

Fix for #160 : empty utf8 quoted not parsed correctly, thanks @jszaszi

2.2.0

Fixes:

  • References header decoding problem #186 - IdHeader can now accept a mix of mime-encoded and non-mime-encoded parts
  • Issue with parsing ReceivedHeaders #183
2.1.1

#184 Adding #[\ReturnTypeWillChange] for PHP8.1 compatibility

Thanks @phpfui

2.1.0

Fixes #165 -- separates email address parsing into its own consumer so invalid characters can be ignored within an '<' and '>' chars representing the email address.

2.0.1

Fix an issue parsing long RFC2231 header values #182

1.3.3

Fixes #182

2.0.0

Huge thank you to the project sponsors who helped make this release happen.

  • Use pimple/pimple for di, refactor initialization:
    • Reconfigure the dependency container entirely, call MailMimePaser::setDependencyContainer
    • Add providers, call MailMimeParser::configureDependencyContainer with an array of providers
  • Parser improvements:
    • Modular parsing separated into classes for better extensibility
    • Dynamic/proxied parsing based on user requests (looking at message headers won't parse all content/children and is therefore very very fast even on larger messages)
    • Stream is no longer copied first, but must be closed after the message object is destroyed (or can be attached to the message)
  • Define and use interfaces instead of concrete classes for better extensibility, change of internal hierarchy that didn't make sense
    • IMessagePart instead of MessagePart, IMimePart instead of MimePart, IUUEncodedPart instead of UUEncodedPart, IMultiPart is new, IMessage instead of Message. HeaderPart and ParentHeaderPart no longer exist.
  • Remove deprecated resource handle methods:
    • Removes IMessage::getTextResourceHandle, IMessage::getHtmlResourceHandle and IMessagePart::getContentResourceHandle
  • Filtering parts is now done with simple callbacks. PartFilter is now just a convenience class with static methods that provides filtering callbacks instead of a concrete class used for filtering.
  • Other minor changes of note:
    • MimePart::getContentDisposition for a MimePart is now limited to returning 'inline' or 'attachment' even if the header has a different value.
    • IMultiPart::removeAllParts now returns the number of parts removed.
2.0.0-beta.1

Proxy parser refactor/fix, testing, documentation.

2.0.0-beta

Thanks to my sponsors @SecuMailer, @mxguardian and @ericlbarnes

Changes and progress (and any issues you find) in #171

1.3.2

Adds support for guzzlehttp/psr7 v2, thanks to @Nielsvanpach

1.3.1

Fixes "SplFixedArray usage is incompatible with PHP 8.0" #151 thanks to @phpfui in #154

1.3.0
1.2.3

Return-Path should be handled as an AddressHeader ( #138 thanks @mariuszkrzaczkowski )

1.2.2

Defaults to multipart/mixed for any multipart type that isn't known #115

1.2.1
  • Deprecate getContentResourceHandle #106
  • Use latest zbateson/stream-decorators
  • Mime-encoded headers for IdHeader #109
  • Travis testing for php 7.4
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules
loco/loco
starfederation/datastar-php
yupmin/modern-phystrix
stephenjude/extended-artisan-commands
lumphp/laravel-macroable
lumphp/laravel-collections
lumphp/laravel-contracts
sermepa/sermepa
arkecosystem/fortify
arkecosystem/ui
owowagency/laravel-resources
gtjamesa/php-standards