[mew-dist 26701] Re: MIME decode error (**B ENCODING ERROR**))

Hideyuki SHIRAI ( 白井秀行 ) shirai at example.com
2005年 11月 29日 (火) 18:02:44 JST


From: Hideyuki SHIRAI (白井秀行) <shirai at example.com> 曰く
Subject: [mew-dist 26698] Re: MIME decode error (**B ENCODING ERROR**))
Message-ID: <20051129.122422.68536077.shirai.hideyuki at example.com>
Date: Tue, 29 Nov 2005 12:24:22 +0900 (JST)

> こういうやりかたが OK なら、「B decode 時のエラー条件緩和」で非
> 常に甘くなった mew-base64-decode-string() はもともとの strict な
> コードに戻して、mew-header-decode() でチェックして warning も出
> す。というのがよいかもです。

というのをやってみました。mew-base64-decode-string() はなにもし
ないで、全部 mew-header-decode() に任せています。

# どうせ異常系なのだから、本当は何文字?のチェックはなし。

-- 
白井秀行 (mailto:shirai at example.com)
-------------- next part --------------
Index: mew-bq.el
===================================================================
RCS file: /cvsmew/mew/mew-bq.el,v
retrieving revision 1.37
diff -u -r1.37 mew-bq.el
--- mew-bq.el	26 May 2005 06:15:47 -0000	1.37
+++ mew-bq.el	29 Nov 2005 08:59:56 -0000
@@ -19,6 +19,9 @@
   `(("B" . ,mew-error-invalid-b-encoding)
     ("Q" . ,mew-error-invalid-q-encoding)))
 
+(defvar mew-header-decode-error-padding-recover
+  `(("B" . t)))
+
 (defsubst mew-header-encode-get-func (b-or-q)
   (cdr (mew-assoc-case-equal b-or-q mew-header-encode-switch 0)))
 
@@ -28,6 +31,9 @@
 (defsubst mew-header-decode-get-error-str (b-or-q)
   (cdr (mew-assoc-case-equal b-or-q mew-header-decode-error-switch 0)))
 
+(defsubst mew-header-decode-get-error-padding-recover (b-or-q)
+  (cdr (mew-assoc-case-equal b-or-q mew-header-decode-error-padding-recover 0)))
+
 (defconst mew-header-decode-regex
   "=\\?\\([^? \t]+\\)\\?\\(.\\)\\?\\([^? \t]+\\)\\?=")
 
@@ -81,9 +87,11 @@
   (let* ((estr (mew-cs-encode-string str hcs)))
     (concat "=?" charset "?" b-or-q "?" (funcall fun estr) "?=")))
 
-(defun mew-header-decode (charset b-or-q estr)
+(defun mew-header-decode (charset b-or-q estr &optional key)
   (let* ((fun (mew-header-decode-get-func b-or-q))
 	 (cs (mew-charset-to-cs charset))
+	 (padlen 0)
+	 (padding 0)
 	 str)
     (when (and mew-use-autoconv-when-unknown
 	       (not (mew-coding-system-p cs)))
@@ -93,6 +101,21 @@
       mew-error-unknown-charset)
      (fun ;; if cs is nil, mew-cs-decode-string does not cs-decode.
       (setq str (funcall fun estr))
+      ;; Rescue padding error
+      (when (and (null str)
+		 mew-decode-broken
+		 (mew-header-decode-get-error-padding-recover b-or-q))
+	(when (string-match "=+$" estr)
+	  (setq estr (substring estr 0 (match-beginning 0)))
+	  (setq padlen (- (match-end 0) (match-beginning 0))))
+	(setq str (catch 'success
+		    (while (< padding 4)
+		      (unless (= padlen padding)
+			(setq str (funcall fun (concat estr (make-string padding ?=))))
+			(when str
+			  (mew-decode-warning-fields key 'padding)
+			  (throw 'success str)))
+		      (setq padding (1+ padding))))))
       (if (null str)
 	  (mew-header-decode-get-error-str b-or-q)
 	(when (and mew-decode-broken
@@ -610,7 +633,8 @@
 	(end (match-end 0))
 	(css (mew-header-decode (mew-match-string 1)
 				(mew-match-string 2)
-				(mew-match-string 3))))
+				(mew-match-string 3)
+				key)))
     (setq css (mew-header-sanity-check-string2 css key))
     (delete-region beg end)
     (insert css)))
@@ -652,7 +676,10 @@
 	(setq wmsg (concat key " has raw text strings.\n")))
        ((eq err 'quoted)
 	(setq level 2)
-	(setq wmsg (concat key " has encoded-words in quoted text.\n"))))
+	(setq wmsg (concat key " has encoded-words in quoted text.\n")))
+       ((eq err 'padding)
+	(setq level 2)
+	(setq wmsg (concat key " has illegal padding in encoded text.\n"))))
       (if (>= level mew-warning-field-level)
 	  (mew-xinfo-set-warning (cons wmsg (mew-xinfo-get-warning)))))))
 
Index: mew-env.el
===================================================================
RCS file: /cvsmew/mew/mew-env.el,v
retrieving revision 1.43
diff -u -r1.43 mew-env.el
--- mew-env.el	7 Jan 2005 04:30:12 -0000	1.43
+++ mew-env.el	29 Nov 2005 08:59:56 -0000
@@ -314,20 +314,7 @@
  ((fboundp 'base64-decode-string)
   (defun mew-base64-decode-string (str64)
     (condition-case nil
-	(let ((r (% (length str64) 4)))
-	  (cond
-	   ((= r 1)
-	    (if (string-match "=$" str64)
-		(setq str64 (substring str64 0 (match-beginning 0)))))
-	   ((= r 2)
-	    (if (string-match "==$" str64)
-		(setq str64 (substring str64 0 (match-beginning 0)))
-	      (setq str64 (concat str64 "=="))))
-	   ((= r 3)
-	    (if (string-match "===$" str64)
-		(setq str64 (substring str64 0 (match-beginning 0)))
-	      (setq str64 (concat str64 "=")))))
-	  (base64-decode-string str64))
+	(base64-decode-string str64)
       (error nil))))
  (t
   (defconst mew-base64-char256


Mew-dist メーリングリストの案内