aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Bochannek2020-09-28 14:09:07 +0200
committerLars Ingebrigtsen2020-09-28 14:09:07 +0200
commiteaf224f88d988d7c8facddf884cc9e2eb192bed8 (patch)
tree32d1a7f53be7aad39ca588c7d1820af8ec73162c
parent232382415d1ff8fdbcb7789e5829c297e6525020 (diff)
downloademacs-eaf224f88d988d7c8facddf884cc9e2eb192bed8.tar.gz
emacs-eaf224f88d988d7c8facddf884cc9e2eb192bed8.zip
Repad the Face header in Gnus
* lisp/gnus/gnus-fun.el (gnus-convert-face-to-png): Use it. * lisp/gnus/gnus-util.el (gnus-base64-repad): New function (bug#43441).
-rw-r--r--lisp/gnus/gnus-fun.el11
-rw-r--r--lisp/gnus/gnus-util.el47
-rw-r--r--test/lisp/gnus/gnus-util-tests.el98
3 files changed, 151 insertions, 5 deletions
diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el
index c95449762e4..2461fd45fd5 100644
--- a/lisp/gnus/gnus-fun.el
+++ b/lisp/gnus/gnus-fun.el
@@ -205,11 +205,12 @@ different input formats."
205(defun gnus-convert-face-to-png (face) 205(defun gnus-convert-face-to-png (face)
206 "Convert FACE (which is base64-encoded) to a PNG. 206 "Convert FACE (which is base64-encoded) to a PNG.
207The PNG is returned as a string." 207The PNG is returned as a string."
208 (mm-with-unibyte-buffer 208 (let ((face (gnus-base64-repad face)))
209 (insert face) 209 (mm-with-unibyte-buffer
210 (ignore-errors 210 (insert face)
211 (base64-decode-region (point-min) (point-max))) 211 (ignore-errors
212 (buffer-string))) 212 (base64-decode-region (point-min) (point-max)))
213 (buffer-string))))
213 214
214;;;###autoload 215;;;###autoload
215(defun gnus-convert-png-to-face (file) 216(defun gnus-convert-png-to-face (file)
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index aa9f137e203..f8126906b87 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -1343,6 +1343,53 @@ forbidden in URL encoding."
1343 (setq tmp (concat tmp str)) 1343 (setq tmp (concat tmp str))
1344 tmp)) 1344 tmp))
1345 1345
1346(defun gnus-base64-repad (str &optional reject-newlines line-length)
1347 "Take a base 64-encoded string and return it padded correctly.
1348Existing padding is ignored.
1349
1350If any combination of CR and LF characters are present and
1351REJECT-NEWLINES is nil, remove them; otherwise raise an error.
1352If LINE-LENGTH is set and the string (or any line in the string
1353if REJECT-NEWLINES is nil) is longer than that number, raise an
1354error. Common line length for input characters are 76 plus CRLF
1355(RFC 2045 MIME), 64 plus CRLF (RFC 1421 PEM), and 1000 including
1356CRLF (RFC 5321 SMTP)."
1357 ;; RFC 4648 specifies that:
1358 ;; - three 8-bit inputs make up a 24-bit group
1359 ;; - the 24-bit group is broken up into four 6-bit values
1360 ;; - each 6-bit value is mapped to one character of the base 64 alphabet
1361 ;; - if the final 24-bit quantum is filled with only 8 bits the output
1362 ;; will be two base 64 characters followed by two "=" padding characters
1363 ;; - if the final 24-bit quantum is filled with only 16 bits the output
1364 ;; will be three base 64 character followed by one "=" padding character
1365 ;;
1366 ;; RFC 4648 section 3 considerations:
1367 ;; - if reject-newlines is nil (default), concatenate multi-line
1368 ;; input (3.1, 3.3)
1369 ;; - if line-length is set, error on input exceeding the limit (3.1)
1370 ;; - reject characters outside base encoding (3.3, also section 12)
1371 (let ((splitstr (split-string str "[\r\n]" t)))
1372 (when (and reject-newlines (> (length splitstr) 1))
1373 (error "Invalid Base64 string"))
1374 (dolist (substr splitstr)
1375 (when (and line-length (> (length substr) line-length))
1376 (error "Base64 string exceeds line-length"))
1377 (when (string-match "[^A-Za-z0-9+/=]" substr)
1378 (error "Invalid Base64 string")))
1379 (let* ((str (string-join splitstr))
1380 (len (length str)))
1381 (when (string-match "=" str)
1382 (setq len (match-beginning 0)))
1383 (concat
1384 (substring str 0 len)
1385 (make-string (/
1386 (- 24
1387 (pcase (mod (* len 6) 24)
1388 (`0 24)
1389 (n n)))
1390 6)
1391 ?=)))))
1392
1346(defun gnus-make-predicate (spec) 1393(defun gnus-make-predicate (spec)
1347 "Transform SPEC into a function that can be called. 1394 "Transform SPEC into a function that can be called.
1348SPEC is a predicate specifier that contains stuff like `or', `and', 1395SPEC is a predicate specifier that contains stuff like `or', `and',
diff --git a/test/lisp/gnus/gnus-util-tests.el b/test/lisp/gnus/gnus-util-tests.el
index 7eadb0de716..ed33be46a3a 100644
--- a/test/lisp/gnus/gnus-util-tests.el
+++ b/test/lisp/gnus/gnus-util-tests.el
@@ -25,6 +25,65 @@
25(require 'ert) 25(require 'ert)
26(require 'gnus-util) 26(require 'gnus-util)
27 27
28(ert-deftest gnus-string> ()
29 ;; Failure paths
30 (should-error (gnus-string> "" 1)
31 :type 'wrong-type-argument)
32 (should-error (gnus-string> "")
33 :type 'wrong-number-of-arguments)
34
35 ;; String tests
36 (should (gnus-string> "def" "abc"))
37 (should (gnus-string> 'def 'abc))
38 (should (gnus-string> "abc" "DEF"))
39 (should (gnus-string> "abc" 'DEF))
40 (should (gnus-string> "αβγ" "abc"))
41 (should (gnus-string> "אבג" "αβγ"))
42 (should (gnus-string> nil ""))
43 (should (gnus-string> "abc" ""))
44 (should (gnus-string> "abc" "ab"))
45 (should-not (gnus-string> "abc" "abc"))
46 (should-not (gnus-string> "abc" "def"))
47 (should-not (gnus-string> "DEF" "abc"))
48 (should-not (gnus-string> 'DEF "abc"))
49 (should-not (gnus-string> "123" "abc"))
50 (should-not (gnus-string> "" "")))
51
52(ert-deftest gnus-string< ()
53 ;; Failure paths
54 (should-error (gnus-string< "" 1)
55 :type 'wrong-type-argument)
56 (should-error (gnus-string< "")
57 :type 'wrong-number-of-arguments)
58
59 ;; String tests
60 (setq case-fold-search nil)
61 (should (gnus-string< "abc" "def"))
62 (should (gnus-string< 'abc 'def))
63 (should (gnus-string< "DEF" "abc"))
64 (should (gnus-string< "DEF" 'abc))
65 (should (gnus-string< "abc" "αβγ"))
66 (should (gnus-string< "αβγ" "אבג"))
67 (should (gnus-string< "" nil))
68 (should (gnus-string< "" "abc"))
69 (should (gnus-string< "ab" "abc"))
70 (should-not (gnus-string< "abc" "abc"))
71 (should-not (gnus-string< "def" "abc"))
72 (should-not (gnus-string< "abc" "DEF"))
73 (should-not (gnus-string< "abc" 'DEF))
74 (should-not (gnus-string< "abc" "123"))
75 (should-not (gnus-string< "" ""))
76
77 ;; gnus-string< checks case-fold-search
78 (setq case-fold-search t)
79 (should (gnus-string< "abc" "DEF"))
80 (should (gnus-string< "abc" 'GHI))
81 (should (gnus-string< 'abc "DEF"))
82 (should (gnus-string< 'GHI 'JKL))
83 (should (gnus-string< "abc" "ΑΒΓ"))
84 (should-not (gnus-string< "ABC" "abc"))
85 (should-not (gnus-string< "def" "ABC")))
86
28(ert-deftest gnus-subsetp () 87(ert-deftest gnus-subsetp ()
29 ;; False for non-lists. 88 ;; False for non-lists.
30 (should-not (gnus-subsetp "1" "1")) 89 (should-not (gnus-subsetp "1" "1"))
@@ -73,4 +132,43 @@
73 (should (equal '("1") (gnus-setdiff '(2 "1" 2) '(2)))) 132 (should (equal '("1") (gnus-setdiff '(2 "1" 2) '(2))))
74 (should (equal '("1" "1") (gnus-setdiff '(2 "1" 2 "1") '(2))))) 133 (should (equal '("1" "1") (gnus-setdiff '(2 "1" 2 "1") '(2)))))
75 134
135(ert-deftest gnus-base64-repad ()
136 (should-error (gnus-base64-repad "" nil nil nil)
137 :type 'wrong-number-of-arguments)
138 (should-error (gnus-base64-repad 1)
139 :type 'wrong-type-argument)
140
141 ;; RFC4648 test vectors
142 (should (equal "" (gnus-base64-repad "")))
143 (should (equal "Zg==" (gnus-base64-repad "Zg==")))
144 (should (equal "Zm8=" (gnus-base64-repad "Zm8=")))
145 (should (equal "Zm9v" (gnus-base64-repad "Zm9v")))
146 (should (equal "Zm9vYg==" (gnus-base64-repad "Zm9vYg==")))
147 (should (equal "Zm9vYmE=" (gnus-base64-repad "Zm9vYmE=")))
148 (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9vYmFy")))
149
150 (should (equal "Zm8=" (gnus-base64-repad "Zm8")))
151 (should (equal "Zg==" (gnus-base64-repad "Zg")))
152 (should (equal "Zg==" (gnus-base64-repad "Zg====")))
153
154 (should-error (gnus-base64-repad " ")
155 :type 'error)
156 (should-error (gnus-base64-repad "Zg== ")
157 :type 'error)
158 (should-error (gnus-base64-repad "Z?\x00g==")
159 :type 'error)
160 ;; line-length
161 (should-error (gnus-base64-repad "Zg====" nil 4)
162 :type 'error)
163 ;; reject-newlines
164 (should-error (gnus-base64-repad "Zm9v\r\nYmFy" t)
165 :type 'error)
166 (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9vYmFy" t)))
167 (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v\r\nYmFy" nil)))
168 (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v\r\nYmFy\n" nil)))
169 (should-error (gnus-base64-repad "Zm9v\r\n YmFy\r\n" nil)
170 :type 'error)
171 (should-error (gnus-base64-repad "Zm9v\r\nYmFy" nil 3)
172 :type 'error))
173
76;;; gnustest-gnus-util.el ends here 174;;; gnustest-gnus-util.el ends here