mm-decode.el (mm-dissect-buffer): Guess content-type if the first token is missing...
authorKatsumi Yamaoka <yamaoka@jpl.org>
Tue, 22 Oct 2013 10:22:25 +0000 (10:22 +0000)
committerKatsumi Yamaoka <yamaoka@jpl.org>
Tue, 22 Oct 2013 10:22:25 +0000 (10:22 +0000)
nndoc.el (nndoc-dissect-mime-parts-sub): Ditto

lisp/ChangeLog
lisp/mm-decode.el
lisp/nndoc.el

index fcd1cdd..617191d 100644 (file)
@@ -1,3 +1,10 @@
+2013-10-22  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * mm-decode.el (mm-dissect-buffer): Guess content-type if the first
+       token is missing in the Content-Type header.
+
+       * nndoc.el (nndoc-dissect-mime-parts-sub): Ditto.
+
 2013-09-18  Glenn Morris  <rgm@gnu.org>
 
        * gnus-util.el (image-size): Declare.
index 941849d..4a9007a 100644 (file)
@@ -672,12 +672,39 @@ MIME-Version header before proceeding."
                                 description)))))
       (if (or (not ctl)
              (not (string-match "/" (car ctl))))
-         (mm-dissect-singlepart
-          (list mm-dissect-default-type)
-          (and cte (intern (downcase (mail-header-strip cte))))
-          no-strict-mime
-          (and cd (mail-header-parse-content-disposition cd))
-          description)
+         (let ((cdl (and cd (mail-header-parse-content-disposition cd))))
+           (mm-dissect-singlepart
+            ;; Guess Content-Type from the file name extention.
+            ;; Some mailer sends a part without type like this:
+            ;;  Content-Type: ; name="IMG_3156.JPG"
+            ;;  Content-Disposition: attachment; filename="IMG_3156.JPG"
+            (list (or
+                   (let ((tem
+                          (or (mail-content-type-get cdl 'filename)
+                              (and ct
+                                   (with-temp-buffer
+                                     (insert ct)
+                                     (goto-char (point-min))
+                                     (and (re-search-forward "\
+;[\t\n ]*name=\\([\"']\\|\\([^\t\n\r ]+\\)\\)" nil t)
+                                          (or (match-string 2)
+                                              (progn
+                                                (goto-char (match-beginning 1))
+                                                (condition-case nil
+                                                    (progn
+                                                      (forward-sexp 1)
+                                                      (buffer-substring
+                                                       (1+ (match-beginning 1))
+                                                       (1- (point))))
+                                                  (error nil))))))))))
+                     (and tem
+                          (setq tem (file-name-extension tem))
+                          (require 'mailcap)
+                          (cdr (assoc (concat "." (downcase tem))
+                                      mailcap-mime-extensions))))
+                   mm-dissect-default-type))
+            (and cte (intern (downcase (mail-header-strip cte))))
+            no-strict-mime cdl description))
        (setq type (split-string (car ctl) "/"))
        (setq subtype (cadr type)
              type (car type))
index b17a7a6..00d9f4d 100644 (file)
@@ -968,15 +968,61 @@ PARENT is the message-ID of the parent summary line, or nil for none."
     (goto-char head-begin)
     (setq content-type (message-fetch-field "Content-Type"))
     (when content-type
-      (when (string-match
-            "^ *\\([^ \t\n/;]+\\)/\\([^ \t\n/;]+\\)" content-type)
+      (with-temp-buffer
+       (insert content-type)
+       (goto-char (point-min))
+       (when (re-search-forward ";[\t\n ]*name=\\([\"']\\|\\([^\t\n\r ]+\\)\\)"
+                                nil t)
+            (setq subject (or (match-string 2)
+                              (progn
+                                (goto-char (match-beginning 1))
+                                (condition-case nil
+                                    (progn
+                                      (forward-sexp 1)
+                                      (buffer-substring
+                                       (1+ (match-beginning 1)) (1- (point))))
+                                  (error nil)))))))
+      (when (or (string-match "^ *\\([^ \t\n/;]+\\)/\\([^ \t\n/;]+\\)"
+                             content-type)
+               ;; Guess Content-Type from the file name extention.
+               ;; Some mailer sends a part without type like this:
+               ;;  Content-Type: ; name="IMG_3156.JPG"
+               ;;  Content-Disposition: attachment; filename="IMG_3156.JPG"
+               (let ((tem (message-fetch-field "Content-Disposition"))
+                     (case-fold-search t)
+                     len)
+                 (when (and
+                        (setq tem
+                              (or (and tem
+                                       (mail-content-type-get
+                                        (mail-header-parse-content-disposition
+                                         tem)
+                                        'filename))
+                                  subject))
+                        (setq tem (file-name-extension tem))
+                        (require 'mailcap)
+                        (setq content-type
+                              (cdr (assoc (concat "." (downcase tem))
+                                          mailcap-mime-extensions)))
+                        (string-match "^ *\\([^ \t\n/;]+\\)/\\([^ \t\n/;]+\\)"
+                                      content-type))
+                   (save-match-data
+                     (goto-char (point-min))
+                     (when (re-search-forward "^Content-Type:\\([^;]*\\);"
+                                              nil t)
+                       (setq len (- (match-end 1) (match-beginning 1)
+                                    (length content-type))
+                             head-end (- head-end len)
+                             body-begin (- body-begin len)
+                             body-end (- body-end len))
+                       (replace-match (concat "Content-Type: " content-type
+                                              ";"))))
+                   t)))
        (setq type (downcase (match-string 1 content-type))
              subtype (downcase (match-string 2 content-type))
              message-rfc822 (and (string= type "message")
                                  (string= subtype "rfc822"))
              multipart-any (string= type "multipart")))
-      (when (string-match ";[ \t\n]*name=\\([^ \t\n;]+\\)" content-type)
-       (setq subject (match-string 1 content-type)))
       (when (string-match "boundary=\"?\\([^\"\n]*[^\" \t\n]\\)" content-type)
        (setq boundary-regexp (concat "^--"
                                      (regexp-quote