Subject: 27.1; [PATCH] Fix incorrectly base64-padded faces in gnus-convert-face-to-png

From: Alex Bochannek <[email-masked]>
Date: Tue, 15 Sep 2020 23:06:53 -0700

Hello!

I noticed a problem with Faces not showing up despite a Face-header
being present in a message. In this particular case,
base64-decode-region failed to decode the header, which had incorrect
(i.e., excessive) padding. A command line and a Web-based decoder
happily ignored the superfluous '='s at the end of the string. Here is
the string in question:

"iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAMFBMVEUwXjFLc0vD0cS7y7zw9PDZ4tkWSRaVrZZ+m39qi2tXfVj////7+/utwK4IPggAOAAJUUA7AAABKklEQVQ4jWPYjQMwDFYJp0NKEKCNJmEf9h8CsimXiL2e33s3/e7F7K2Cs3f3dCMkQkMKj4YuCY3K3iR+e7fMaiSjvkX0/5cFGrWpe2uLzOpaExUVqMS/8PX/Re5ey960OLBTZpFA8+IlSBKPQ92zNyUUBsosN58uIY0k8f+/ONCoYytkVuhWzVwNkYiYbqk5M3NmOVBi41YZ8RsGF7shEtFb5KJ3r969CyixM7OTPeFUxG2IxLO8/9/SvqXlc+/x3h295YzLlj2nIRJQj//nRvc5TEIal8RsXBLVuCQwIgoq/u80DomP6HEOk/iOS+IJLonZOCT+ReOQ+Lkbh0QKLonbOCR+7MYhsRqHBJrVcIl/1TgklqKLQyQ+tGKIgyQOqXpjig94diZRAgAXmDX6jyWafAAAAABJRU5ErkJggg======"

The correct number of '='s here is two.

I don't suspect this problem is widespread in other uses of the base64
decoder, so it seems appropriate to me to just patch
gnus-convert-face-to-png to generate the right amount of padding.

diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el
index c95449762e..f1773db29a 100644
--- a/lisp/gnus/gnus-fun.el
+++ b/lisp/gnus/gnus-fun.el
@@ -205,11 +205,27 @@ gnus-face-encode
 (defun gnus-convert-face-to-png (face)
   "Convert FACE (which is base64-encoded) to a PNG.
 The PNG is returned as a string."
-  (mm-with-unibyte-buffer
-    (insert face)
-    (ignore-errors
-      (base64-decode-region (point-min) (point-max)))
-    (buffer-string)))
+  (let ((face (replace-regexp-in-string "[^[:graph:]]" "" face)))
+    ;; Calculate correct base64 padding
+    (if (string-match "=" face)
+	(let ((length (match-beginning 0))
+	      (padding nil))
+	  (progn (setq padding
+		       (/
+			(- 24
+			   (pcase (mod (* length 6) 24)
+			     (`0 24)
+			     (n n)))
+			6))
+		 (setq face (concat
+			     (substring face 0
+					(match-beginning 0))
+			     (make-string padding ?=))))))
+    (mm-with-unibyte-buffer
+      (insert face)
+      (ignore-errors
+	(base64-decode-region (point-min) (point-max)))
+      (buffer-string))))
 
 ;;;###autoload
 (defun gnus-convert-png-to-face (file)

-- 
Alex. ([email-masked])