(rfc2231-parse-string): Decode encoded value after concatenating segments
[gnus] / lisp / rfc2231.el
index 3728b78..05a3440 100644 (file)
@@ -53,8 +53,7 @@ must never cause a Lisp error."
     (let ((ttoken (ietf-drums-token-to-list ietf-drums-text-token))
          (stoken (ietf-drums-token-to-list ietf-drums-tspecials))
          (ntoken (ietf-drums-token-to-list "0-9"))
-         c type attribute encoded number prev-attribute vals
-         prev-encoded parameters value)
+         c type attribute encoded number parameters value)
       (ietf-drums-init
        (condition-case nil
           (mail-header-remove-whitespace
@@ -142,19 +141,6 @@ must never cause a Lisp error."
                            (setq c (char-after)))))
                    (setq number nil
                          encoded nil))
-                 ;; See if we have any previous continuations.
-                 (when (and prev-attribute
-                            (not (eq prev-attribute attribute)))
-                   (setq vals
-                         (mapconcat 'cdr (sort vals 'car-less-than-car) ""))
-                   (push (cons prev-attribute
-                               (if prev-encoded
-                                   (rfc2231-decode-encoded-string vals)
-                                 vals))
-                         parameters)
-                   (setq prev-attribute nil
-                         vals nil
-                         prev-encoded nil))
                  (unless (eq c ?=)
                    (error "Invalid header: %s" string))
                  (forward-char 1)
@@ -187,33 +173,33 @@ must never cause a Lisp error."
                             (point)))))
                   (t
                    (error "Invalid header: %s" string)))
-                 (if number
-                     (progn
-                       (push (cons number value) vals)
-                       (setq prev-attribute attribute
-                             prev-encoded encoded))
-                   (push (cons attribute
-                               (if encoded
-                                   (rfc2231-decode-encoded-string value)
-                                 value))
-                         parameters))))
-
-             ;; Take care of any final continuations.
-             (when prev-attribute
-               (setq vals (mapconcat 'cdr (sort vals 'car-less-than-car) ""))
-               (push (cons prev-attribute
-                           (if prev-encoded
-                               (rfc2231-decode-encoded-string vals)
-                             vals))
-                     parameters)))
+                 (push (list attribute value number encoded)
+                       parameters))))
          (error
           (setq parameters nil)
-          (if signal-error
-              (signal (car err) (cdr err))
-            ;;(message "%s" (error-message-string err))
-            )))
+          (when signal-error
+            (signal (car err) (cdr err)))))
 
-       (cons type (nreverse parameters))))))
+       ;; Now collect and concatenate continuation parameters.
+       (let ((cparams nil)
+             elem)
+         (loop for (attribute value part encoded)
+               in (sort parameters (lambda (e1 e2)
+                                     (< (or (caddr e1) 0)
+                                        (or (caddr e2) 0))))
+               do (if (or (not (setq elem (assq attribute cparams)))
+                          (and (numberp part)
+                               (zerop part)))
+                      (push (list attribute value encoded) cparams)
+                    (setcar (cdr elem) (concat (cadr elem) value))))
+         ;; Finally decode encoded values.
+         (cons type (mapcar
+                     (lambda (elem)
+                       (cons (car elem)
+                             (if (nth 2 elem)
+                                 (rfc2231-decode-encoded-string (nth 1 elem))
+                               (nth 1 elem))))
+                     (nreverse cparams))))))))
 
 (defun rfc2231-decode-encoded-string (string)
   "Decode an RFC2231-encoded string.
@@ -227,7 +213,7 @@ These look like:
   (let ((coding-system (mm-charset-to-coding-system (match-string 1 string)))
        ;;(language (match-string 2 string))
        (value (match-string 3 string)))
-    (mm-with-multibyte-buffer
+    (mm-with-unibyte-buffer
       (insert value)
       (goto-char (point-min))
       (while (search-forward "%" nil t)
@@ -236,9 +222,9 @@ These look like:
             (string-to-number (buffer-substring (point) (+ (point) 2)) 16)
           (delete-region (1- (point)) (+ (point) 2)))))
       ;; Decode using the charset, if any.
-      (unless (memq coding-system '(nil ascii))
-       (mm-decode-coding-region (point-min) (point-max) coding-system))
-      (buffer-string))))
+      (if (memq coding-system '(nil ascii))
+         (buffer-string)
+       (mm-decode-coding-string (buffer-string) coding-system)))))
 
 (defun rfc2231-encode-string (param value)
   "Return and PARAM=VALUE string encoded according to RFC2231.
@@ -252,7 +238,7 @@ the result of this function."
        ;; Don't make lines exceeding 76 column.
        (limit (- 74 (length param)))
        spacep encodep charsetp charset broken)
-    (with-temp-buffer
+    (mm-with-multibyte-buffer
       (insert value)
       (goto-char (point-min))
       (while (not (eobp))
@@ -268,6 +254,7 @@ the result of this function."
        (forward-char 1))
       (when charsetp
        (setq charset (mm-encode-body)))
+      (mm-disable-multibyte)
       (cond
        ((or encodep charsetp
            (progn