Security Advisories (10)
CVE-2026-116264 (2026-10-28)

MIME::Field::ParamVal versions before 5.521 for Perl allow one invalid Content-Type parameter to hide the parameters after it, including the multipart boundary. Parameter parsing stops at the first parameter whose name it cannot read, such as x:y=1 or a name containing an 8-bit byte, and drops every parameter after it. When the boundary is among them, MIME::Parser keeps the multipart body as a single undecoded part without marking the parse as ambiguous. Mail readers that skip the invalid parameter still find the boundary. A remote sender can hide an attachment from a filter that relies on ambiguous_content() while the recipient's mail client shows it.

CVE-2026-116265 (2026-10-28)

MIME::Field::ParamVal versions before 5.521 for Perl do not flag an ambiguous multipart boundary written as RFC 2231 continuations. The boundary ambiguity checks look only at a plain boundary= parameter, and a boundary split into RFC 2231 sections (boundary*0=, boundary*1= and so on) is joined after they have run. A repeated section number is concatenated rather than reported as a duplicate. From version 5.518, an encoded word or trailing whitespace in such a boundary also goes unflagged, although multipart_boundary() decodes or strips it. A remote sender can make MIME::Parser split a message on a different boundary than other mail readers, hiding an attachment from a filter that relies on ambiguous_content() while the recipient's mail client shows it.

CVE-2026-116266 (2026-10-28)

MIME::Head versions from 5.518 before 5.521 for Perl decode a partly encoded multipart boundary without flagging the parse as ambiguous. The multipart_boundary() method decodes RFC 2047 encoded words anywhere in the boundary, but the ambiguity check only fires when the whole value is one encoded word. A boundary such as abc=?us-ascii?Q?def?= is used as abcdef, and ambiguous_content() returns false. Encoded words are not allowed in parameters, so other mail readers split the message on the literal value. A remote sender can hide an attachment from a filter that relies on ambiguous_content() while the recipient's mail client shows it.

CVE-2026-116267 (2026-10-28)

MIME::Parser versions before 5.521 for Perl allow memory exhaustion via indented error messages from a truncated, deeply nested message. Each stored parser diagnostic is indented by three spaces per nesting level. When a message nested N levels deep ends without its closing boundaries, every level logs an error at its own depth, so the stored diagnostics grow with the square of N. The defaults place no limit on nesting depth.

CVE-2026-116268 (2026-10-28)

MIME::Field::ParamVal versions before 5.521 for Perl allow CPU exhaustion via unclosed comments in header parameters. The comment pattern used to parse Content-Type and Content-Disposition parameters scans from each "(" to the next ")". In a field with no ")", every "(" scans to the end of the header and fails, so parsing takes time quadratic in the header length. The field is parsed again on each attribute lookup, several times per MIME entity. A 40 KB header takes about 7 seconds to parse once.

CVE-2026-116269 (2026-10-28)

MIME::Field::ParamVal versions before 5.521 for Perl turn an RFC 2231 filename with a hyphenated language tag into an empty recommended filename. A parameter such as filename*=utf-8'en-US'payload.exe is converted to an encoded word with the language tag appended to the charset. The decoder strips the language suffix only when it is a single word, so it cannot resolve the charset UTF-8*EN-US and returns an empty string. The recommended_filename() method returns that empty string rather than falling back to the name parameter. Other mail readers return payload.exe. A remote sender can get an attachment past a policy that checks file extensions on the recommended filename.

CVE-2026-116270 (2026-10-28)

MIME::Words versions before 5.521 for Perl allow memory exhaustion via repeated "=?" sequences in decode_mimewords. For each "=?" that does not start a complete encoded word, decode_mimewords appends an error message containing the whole input string to $@. A boundary of 8,000 "=?" pairs (16,000 bytes) adds 8,000 copies of itself to $@, about 128 MB. From version 5.518, MIME::Parser decodes every multipart boundary this way, so a remote sender can exhaust the memory of the parsing process with one Content-Type header.

CVE-2026-116271 (2026-10-28)

MIME::Parser::FileUnder versions before 5.521 for Perl reuse a pre-created output directory and follow symlinks in it, letting local users redirect attachment writes. Each message is written to a directory named msg-<time>-<pid>-<n> under the output base, and an existing directory of that name is used as is. A file name counts as unused when nothing exists at that path, which holds for a dangling symlink, and the body file is then opened in a way that follows the link. When the output base is writable by other users, as with output_under("/tmp"), a local user can pre-create the directory with a symlink named like an attachment. The parser then writes the attachment to the link target with the privileges of the parsing process.

CVE-2026-116272 (2026-10-28)

MIME::Field::ParamVal versions before 5.521 for Perl do not flag a duplicate boundary parameter whose name contains a nested comment. A parameter written boundary((c))="A" or boundary(\))="A" is stored under that literal name rather than as boundary. A second boundary parameter is then not reported as a duplicate, and MIME::Parser splits the message on it. Readers that skip comments as RFC 5322 allows take the first boundary instead. A remote sender can hide an attachment from a filter that relies on ambiguous_content() while the recipient's mail client shows it.

CVE-2026-116273 (2026-10-28)

MIME::Parser versions before 5.521 for Perl set no limit on the number of message parts by default, allowing memory exhaustion. The max_parts option defaulted to -1, which disables the limit, so a parser created with default settings builds an entity for every part however many a message has. Version 5.521 sets max_parts to 1000 and max_depth to 64 by default. Setting either to -1 still removes the limit.

NAME

MIME::WordDecoder - decode RFC 2047 encoded words to a local representation

WARNING: Most of this module is deprecated and may disappear. The only function you should use for MIME decoding is "mime_to_perl_string".

SYNOPSIS

See MIME::Words for the basics of encoded words. See "DESCRIPTION" for how this class works.

use MIME::WordDecoder;


### Get the default word-decoder (used by unmime()):
$wd = default MIME::WordDecoder;

### Get a word-decoder which maps to ISO-8859-1 (Latin1):
$wd = supported MIME::WordDecoder "ISO-8859-1";


### Decode a MIME string (e.g., into Latin1) via the default decoder:
$str = $wd->decode('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld>');

### Decode a string using the default decoder, non-OO style:
$str = unmime('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld>');

### Decode a string to an internal Perl string, non-OO style
### The result is likely to have the UTF8 flag ON.
$str = mime_to_perl_string('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld>');

DESCRIPTION

WARNING: Most of this module is deprecated and may disappear. It duplicates (badly) the function of the standard 'Encode' module. The only function you should rely on is mime_to_perl_string.

A MIME::WordDecoder consists, fundamentally, of a hash which maps a character set name (US-ASCII, ISO-8859-1, etc.) to a subroutine which knows how to take bytes in that character set and turn them into the target string representation. Ideally, this target representation would be Unicode, but we don't want to overspecify the translation that takes place: if you want to convert MIME strings directly to Big5, that's your own decision.

The subroutine will be invoked with two arguments: DATA (the data in the given character set), and CHARSET (the upcased character set name).

For example:

    ### Keep 7-bit characters as-is, convert 8-bit characters to '#':
    sub keep7bit {
	local $_ = shift;
	tr/\x00-\x7F/#/c;
	$_;
    }

Here's a decoder which uses that:

### Construct a decoder:
$wd = MIME::WordDecoder->new({'US-ASCII'   => "KEEP",   ### sub { $_[0] }
                              'ISO-8859-1' => \&keep7bit,
                              'ISO-8859-2' => \&keep7bit,
                              'Big5'       => "WARN",
                              '*'          => "DIE"});

### Convert some MIME text to a pure ASCII string...
$ascii = $wd->decode('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld>');

### ...which will now hold: "To: Keld J#rn Simonsen <keld>"

The UTF-8 built-in decoder decodes everything into Perl's internal string format, possibly turning on the internal UTF8 flag. Use it like this:

$wd = supported MIME::WordDecoder 'UTF-8';
$perl_string = $wd->decode('To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld>');
# perl_string will be a valid UTF-8 string with the "UTF8" flag set.

Generally, you should use the UTF-8 decoder in preference to "unmime".

PUBLIC INTERFACE

default [DECODER]

Class method. Get/set the default DECODER object.

supported CHARSET, [DECODER]

Class method. If just CHARSET is given, returns a decoder object which maps data into that character set (the character set is forced to all-uppercase).

$wd = supported MIME::WordDecoder "ISO-8859-1";

If DECODER is given, installs such an object:

    MIME::WordDecoder->supported("ISO-8859-1" =>
				 (new MIME::WordDecoder::ISO_8859 "1"));

You should not override this method.

new [\@HANDLERS]

Class method, constructor. If \@HANDLERS is given, then @HANDLERS is passed to handler() to initialize the internal map.

handler CHARSET=>\&SUBREF, ...

Instance method. Set the handler SUBREF for a given CHARSET, for as many pairs as you care to supply.

When performing the translation of a MIME-encoded string, a given SUBREF will be invoked when translating a block of text in character set CHARSET. The subroutine will be invoked with the following arguments:

DATA    - the data in the given character set.
CHARSET - the upcased character set name, which may prove useful
          if you are using the same SUBREF for multiple CHARSETs.
DECODER - the decoder itself, if it contains configuration information
          that your handler function needs.

For example:

    $wd = new MIME::WordDecoder;
    $wd->handler('US-ASCII'   => "KEEP");
    $wd->handler('ISO-8859-1' => \&handle_latin1,
		 'ISO-8859-2' => \&handle_latin1,
		 '*'          => "DIE");

Notice that, much as with %SIG, the SUBREF can also be taken from a set of special keywords:

KEEP     Pass data through unchanged.
IGNORE   Ignore data in this character set, without warning.
WARN     Ignore data in this character set, with warning.
DIE      Fatal exception with "can't handle character set" message.

The subroutine for the special CHARSET of 'raw' is used for raw (non-MIME-encoded) text, which is supposed to be US-ASCII. The handler for 'raw' defaults to whatever was specified for 'US-ASCII' at the time of construction.

The subroutine for the special CHARSET of '*' is used for any unrecognized character set. The default action for '*' is WARN.

decode STRING

Instance method. Decode a STRING which might contain MIME-encoded components into a local representation (e.g., UTF-8, etc.).

unmime STRING

Function, exported. Decode the given STRING using the default() decoder. See default().

You should consider using the UTF-8 decoder instead. It decodes MIME strings into Perl's internal string format.

mime_to_perl_string

Function, exported. Decode the given STRING into an internal Perl Unicode string. You should use this function in preference to all others.

The result of mime_to_perl_string is likely to have Perl's UTF8 flag set.

SUBCLASSES

MIME::WordDecoder::ISO_8859

A simple decoder which keeps US-ASCII and the 7-bit characters of ISO-8859 character sets and UTF8, and also keeps 8-bit characters from the indicated character set.

### Construct:
$wd = new MIME::WordDecoder::ISO_8859 2;    ### ISO-8859-2

### What to translate unknown characters to (can also use empty):
### Default is "?".
$wd->unknown("?");

### Collapse runs of unknown characters to a single unknown()?
### Default is false.
$wd->collapse(1);

According to http://czyborra.com/charsets/iso8859.html (ca. November 2000):

ISO 8859 is a full series of 10 (and soon even more) standardized multilingual single-byte coded (8bit) graphic character sets for writing in alphabetic languages:

 1. Latin1 (West European)
 2. Latin2 (East European)
 3. Latin3 (South European)
 4. Latin4 (North European)
 5. Cyrillic
 6. Arabic
 7. Greek
 8. Hebrew
 9. Latin5 (Turkish)
10. Latin6 (Nordic)

The ISO 8859 charsets are not even remotely as complete as the truly great Unicode but they have been around and usable for quite a while (first registered Internet charsets for use with MIME) and have already offered a major improvement over the plain 7bit US-ASCII.

Characters 0 to 127 are always identical with US-ASCII and the positions 128 to 159 hold some less used control characters: the so-called C1 set from ISO 6429.

MIME::WordDecoder::US_ASCII

A subclass of the ISO-8859-1 decoder which discards 8-bit characters. You're probably better off using ISO-8859-1.

SEE ALSO

MIME::Tools

AUTHOR

Eryq (eryq@zeegee.com), ZeeGee Software Inc (http://www.zeegee.com). Dianne Skoll (dianne@skoll.ca)