diff --git a/include/class.mailparse.php b/include/class.mailparse.php
index b9ab3c33ff34fd44496a92affbc38a276fc418b9..b02f2448a98a370cc0901231b11b435288d3c599 100644
--- a/include/class.mailparse.php
+++ b/include/class.mailparse.php
@@ -199,18 +199,60 @@ class Mail_Parse {
         return Format::encode($text, $charset, $encoding);
     }
 
+    /**
+     * Decodes filenames given in the content-disposition header according
+     * to RFC5987, such as filename*=utf-8''filename.png. Note that the
+     * language sub-component is defined in RFC5646, and that the filename
+     * is URL encoded (in the charset specified)
+     */
+    function decodeRfc5987($filename) {
+        $match = array();
+        if (preg_match("/([\w!#$%&+^_`{}~-]+)'([\w-]*)'(.*)$/",
+                $filename, $match))
+            // XXX: Currently we don't care about the language component.
+            //      The  encoding hint is sufficient.
+            return self::mime_encode(urldecode($match[3]), $match[1]);
+        else
+            return $filename;
+    }
+
     function getAttachments($part=null){
 
         if($part==null)
             $part=$this->getStruct();
 
-        if($part && $part->disposition
-                && (!strcasecmp($part->disposition,'attachment')
-                    || !strcasecmp($part->disposition,'inline')
-                    || !strcasecmp($part->ctype_primary,'image'))){
-
-            if(!($filename=$part->d_parameters['filename']) && $part->d_parameters['filename*'])
-                $filename=$part->d_parameters['filename*']; //Do we need to decode?
+        /* Consider this part as an attachment if
+         *   * It has a Content-Disposition header
+         *     * AND it is specified as either 'attachment' or 'inline'
+         *   * The Content-Type header specifies
+         *     * type is image/* or application/*
+         *     * has a name parameter
+         */
+        if($part && (
+                ($part->disposition
+                    && (!strcasecmp($part->disposition,'attachment')
+                        || !strcasecmp($part->disposition,'inline'))
+                )
+                || (!strcasecmp($part->ctype_primary,'image')
+                    || !strcasecmp($part->ctype_primary,'application')))) {
+
+            if (isset($part->d_parameters['filename']))
+                $filename = $part->d_parameters['filename'];
+            elseif (isset($part->d_parameters['filename*']))
+                // Support RFC 6266, section 4.3 and RFC, and RFC 5987
+                $filename = self::decodeRfc5987(
+                    $part->d_parameters['filename*']);
+
+            // Support attachments that do not specify a content-disposition
+            // but do specify a "name" parameter in the content-type header.
+            elseif (isset($part->ctype_parameters['name']))
+                $filename=$part->ctype_parameters['name'];
+            elseif (isset($part->ctype_parameters['name*']))
+                $filename = self::decodeRfc5987(
+                    $part->ctype_parameters['name*']);
+            else
+                // Not an attachment?
+                return false;
 
             $file=array(
                     'name'  => $filename,