diff options
| author | Mattias Engdegård | 2021-12-20 18:17:23 +0100 |
|---|---|---|
| committer | Mattias Engdegård | 2021-12-20 20:22:09 +0100 |
| commit | a34650acff3740980ef23d900d35004bcfe2ef04 (patch) | |
| tree | 5e34b2538df2849832e3971bc7d0cd9546b5adc9 | |
| parent | 27be90154d1a4b19efe30c97f221b29e3becc920 (diff) | |
| download | emacs-a34650acff3740980ef23d900d35004bcfe2ef04.tar.gz emacs-a34650acff3740980ef23d900d35004bcfe2ef04.zip | |
Fix sloppy base64 acceptance of some multibyte characters
The base64 encoding functions incorrectly accepted some multibyte
characters; stop doing that (bug#52670).
* src/fns.c (base64_encode_1): Reject all multibyte characters.
* test/src/fns-tests.el (fns-tests-base64-encode-string)
(fns-test-base64url-encode-region)
(fns-test-base64url-encode-string): Add tests.
* doc/lispref/text.texi (Base 64): Rephrase outdated manual text.
* etc/NEWS: Add a notice.
| -rw-r--r-- | doc/lispref/text.texi | 5 | ||||
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | src/fns.c | 6 | ||||
| -rw-r--r-- | test/src/fns-tests.el | 16 |
4 files changed, 26 insertions, 9 deletions
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 5ab5e5715f0..9771d8a7ed9 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi | |||
| @@ -4793,9 +4793,8 @@ converting to and from this code. | |||
| 4793 | This function converts the region from @var{beg} to @var{end} into base | 4793 | This function converts the region from @var{beg} to @var{end} into base |
| 4794 | 64 code. It returns the length of the encoded text. An error is | 4794 | 64 code. It returns the length of the encoded text. An error is |
| 4795 | signaled if a character in the region is multibyte, i.e., in a | 4795 | signaled if a character in the region is multibyte, i.e., in a |
| 4796 | multibyte buffer the region must contain only characters from the | 4796 | multibyte buffer the region must contain only ASCII characters or raw |
| 4797 | charsets @code{ascii}, @code{eight-bit-control} and | 4797 | bytes. |
| 4798 | @code{eight-bit-graphic}. | ||
| 4799 | 4798 | ||
| 4800 | Normally, this function inserts newline characters into the encoded | 4799 | Normally, this function inserts newline characters into the encoded |
| 4801 | text, to avoid overlong lines. However, if the optional argument | 4800 | text, to avoid overlong lines. However, if the optional argument |
| @@ -848,6 +848,14 @@ This change is now applied in 'dired-insert-directory'. | |||
| 848 | 'unify-8859-on-decoding-mode', 'unify-8859-on-encoding-mode', | 848 | 'unify-8859-on-decoding-mode', 'unify-8859-on-encoding-mode', |
| 849 | 'vc-arch-command'. | 849 | 'vc-arch-command'. |
| 850 | 850 | ||
| 851 | +++ | ||
| 852 | ** Base64 encoding no longer tolerates latin-1 input. | ||
| 853 | The functions 'base64-encode-string', 'base64url-encode-string', | ||
| 854 | 'base64-encode-region' and 'base64url-encode-region' no longer accept | ||
| 855 | characters in the range U+0080..U+00FF as substitutes for single bytes | ||
| 856 | in the range 128..255, but signal an error for all multibyte characters. | ||
| 857 | The input must be encoded text. | ||
| 858 | |||
| 851 | 859 | ||
| 852 | * Lisp Changes in Emacs 29.1 | 860 | * Lisp Changes in Emacs 29.1 |
| 853 | 861 | ||
| @@ -3653,7 +3653,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length, | |||
| 3653 | c = string_char_and_length ((unsigned char *) from + i, &bytes); | 3653 | c = string_char_and_length ((unsigned char *) from + i, &bytes); |
| 3654 | if (CHAR_BYTE8_P (c)) | 3654 | if (CHAR_BYTE8_P (c)) |
| 3655 | c = CHAR_TO_BYTE8 (c); | 3655 | c = CHAR_TO_BYTE8 (c); |
| 3656 | else if (c >= 256) | 3656 | else if (c >= 128) |
| 3657 | return -1; | 3657 | return -1; |
| 3658 | i += bytes; | 3658 | i += bytes; |
| 3659 | } | 3659 | } |
| @@ -3696,7 +3696,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length, | |||
| 3696 | c = string_char_and_length ((unsigned char *) from + i, &bytes); | 3696 | c = string_char_and_length ((unsigned char *) from + i, &bytes); |
| 3697 | if (CHAR_BYTE8_P (c)) | 3697 | if (CHAR_BYTE8_P (c)) |
| 3698 | c = CHAR_TO_BYTE8 (c); | 3698 | c = CHAR_TO_BYTE8 (c); |
| 3699 | else if (c >= 256) | 3699 | else if (c >= 128) |
| 3700 | return -1; | 3700 | return -1; |
| 3701 | i += bytes; | 3701 | i += bytes; |
| 3702 | } | 3702 | } |
| @@ -3721,7 +3721,7 @@ base64_encode_1 (const char *from, char *to, ptrdiff_t length, | |||
| 3721 | c = string_char_and_length ((unsigned char *) from + i, &bytes); | 3721 | c = string_char_and_length ((unsigned char *) from + i, &bytes); |
| 3722 | if (CHAR_BYTE8_P (c)) | 3722 | if (CHAR_BYTE8_P (c)) |
| 3723 | c = CHAR_TO_BYTE8 (c); | 3723 | c = CHAR_TO_BYTE8 (c); |
| 3724 | else if (c >= 256) | 3724 | else if (c >= 128) |
| 3725 | return -1; | 3725 | return -1; |
| 3726 | i += bytes; | 3726 | i += bytes; |
| 3727 | } | 3727 | } |
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index bec5c03f9e7..63423f622f8 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el | |||
| @@ -318,7 +318,10 @@ | |||
| 318 | (should (equal (base64-encode-string "fooba") "Zm9vYmE=")) | 318 | (should (equal (base64-encode-string "fooba") "Zm9vYmE=")) |
| 319 | (should (equal (base64-encode-string "foobar") "Zm9vYmFy")) | 319 | (should (equal (base64-encode-string "foobar") "Zm9vYmFy")) |
| 320 | (should (equal (base64-encode-string "\x14\xfb\x9c\x03\xd9\x7e") "FPucA9l+")) | 320 | (should (equal (base64-encode-string "\x14\xfb\x9c\x03\xd9\x7e") "FPucA9l+")) |
| 321 | (should (equal (base64-encode-string "\x14\xfb\x9c\x03\xd9\x7f") "FPucA9l/"))) | 321 | (should (equal (base64-encode-string "\x14\xfb\x9c\x03\xd9\x7f") "FPucA9l/")) |
| 322 | |||
| 323 | (should-error (base64-encode-string "ƒ")) | ||
| 324 | (should-error (base64-encode-string "ü"))) | ||
| 322 | 325 | ||
| 323 | (ert-deftest fns-test-base64url-encode-region () | 326 | (ert-deftest fns-test-base64url-encode-region () |
| 324 | ;; url variant with padding | 327 | ;; url variant with padding |
| @@ -360,7 +363,11 @@ | |||
| 360 | (should (equal (fns-tests--with-region base64url-encode-region (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7e" 10) t) | 363 | (should (equal (fns-tests--with-region base64url-encode-region (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7e" 10) t) |
| 361 | (fns-tests--string-repeat "FPucA9l-" 10))) | 364 | (fns-tests--string-repeat "FPucA9l-" 10))) |
| 362 | (should (equal (fns-tests--with-region base64url-encode-region (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7f" 10) t) | 365 | (should (equal (fns-tests--with-region base64url-encode-region (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7f" 10) t) |
| 363 | (fns-tests--string-repeat "FPucA9l_" 10)))) | 366 | (fns-tests--string-repeat "FPucA9l_" 10))) |
| 367 | |||
| 368 | (should-error (fns-tests--with-region base64url-encode-region "ƒ")) | ||
| 369 | (should-error (fns-tests--with-region base64url-encode-region "ü"))) | ||
| 370 | |||
| 364 | 371 | ||
| 365 | (ert-deftest fns-test-base64url-encode-string () | 372 | (ert-deftest fns-test-base64url-encode-string () |
| 366 | ;; url variant with padding | 373 | ;; url variant with padding |
| @@ -394,7 +401,10 @@ | |||
| 394 | (should (equal (base64url-encode-string (fns-tests--string-repeat "fooba" 15) t) (fns-tests--string-repeat "Zm9vYmFmb29iYWZvb2Jh" 5))) | 401 | (should (equal (base64url-encode-string (fns-tests--string-repeat "fooba" 15) t) (fns-tests--string-repeat "Zm9vYmFmb29iYWZvb2Jh" 5))) |
| 395 | (should (equal (base64url-encode-string (fns-tests--string-repeat "foobar" 15) t) (concat (fns-tests--string-repeat "Zm9vYmFyZm9vYmFy" 7) "Zm9vYmFy"))) | 402 | (should (equal (base64url-encode-string (fns-tests--string-repeat "foobar" 15) t) (concat (fns-tests--string-repeat "Zm9vYmFyZm9vYmFy" 7) "Zm9vYmFy"))) |
| 396 | (should (equal (base64url-encode-string (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7e" 10) t) (fns-tests--string-repeat "FPucA9l-" 10))) | 403 | (should (equal (base64url-encode-string (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7e" 10) t) (fns-tests--string-repeat "FPucA9l-" 10))) |
| 397 | (should (equal (base64url-encode-string (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7f" 10) t) (fns-tests--string-repeat "FPucA9l_" 10)))) | 404 | (should (equal (base64url-encode-string (fns-tests--string-repeat "\x14\xfb\x9c\x03\xd9\x7f" 10) t) (fns-tests--string-repeat "FPucA9l_" 10))) |
| 405 | |||
| 406 | (should-error (base64url-encode-string "ƒ")) | ||
| 407 | (should-error (base64url-encode-string "ü"))) | ||
| 398 | 408 | ||
| 399 | (ert-deftest fns-tests-base64-decode-string () | 409 | (ert-deftest fns-tests-base64-decode-string () |
| 400 | ;; standard variant RFC2045 | 410 | ;; standard variant RFC2045 |