diff options
| author | Alex Bochannek | 2020-09-28 14:09:07 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2020-09-28 14:09:07 +0200 |
| commit | eaf224f88d988d7c8facddf884cc9e2eb192bed8 (patch) | |
| tree | 32d1a7f53be7aad39ca588c7d1820af8ec73162c | |
| parent | 232382415d1ff8fdbcb7789e5829c297e6525020 (diff) | |
| download | emacs-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.el | 11 | ||||
| -rw-r--r-- | lisp/gnus/gnus-util.el | 47 | ||||
| -rw-r--r-- | test/lisp/gnus/gnus-util-tests.el | 98 |
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. |
| 207 | The PNG is returned as a string." | 207 | The 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. | ||
| 1348 | Existing padding is ignored. | ||
| 1349 | |||
| 1350 | If any combination of CR and LF characters are present and | ||
| 1351 | REJECT-NEWLINES is nil, remove them; otherwise raise an error. | ||
| 1352 | If LINE-LENGTH is set and the string (or any line in the string | ||
| 1353 | if REJECT-NEWLINES is nil) is longer than that number, raise an | ||
| 1354 | error. Common line length for input characters are 76 plus CRLF | ||
| 1355 | (RFC 2045 MIME), 64 plus CRLF (RFC 1421 PEM), and 1000 including | ||
| 1356 | CRLF (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. |
| 1348 | SPEC is a predicate specifier that contains stuff like `or', `and', | 1395 | SPEC 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 |