aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Engdegård2021-12-20 18:17:23 +0100
committerMattias Engdegård2021-12-20 20:22:09 +0100
commita34650acff3740980ef23d900d35004bcfe2ef04 (patch)
tree5e34b2538df2849832e3971bc7d0cd9546b5adc9
parent27be90154d1a4b19efe30c97f221b29e3becc920 (diff)
downloademacs-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.texi5
-rw-r--r--etc/NEWS8
-rw-r--r--src/fns.c6
-rw-r--r--test/src/fns-tests.el16
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.
4793This function converts the region from @var{beg} to @var{end} into base 4793This function converts the region from @var{beg} to @var{end} into base
479464 code. It returns the length of the encoded text. An error is 479464 code. It returns the length of the encoded text. An error is
4795signaled if a character in the region is multibyte, i.e., in a 4795signaled if a character in the region is multibyte, i.e., in a
4796multibyte buffer the region must contain only characters from the 4796multibyte buffer the region must contain only ASCII characters or raw
4797charsets @code{ascii}, @code{eight-bit-control} and 4797bytes.
4798@code{eight-bit-graphic}.
4799 4798
4800Normally, this function inserts newline characters into the encoded 4799Normally, this function inserts newline characters into the encoded
4801text, to avoid overlong lines. However, if the optional argument 4800text, to avoid overlong lines. However, if the optional argument
diff --git a/etc/NEWS b/etc/NEWS
index 24f3da8f96f..57fe40c4881 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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.
853The functions 'base64-encode-string', 'base64url-encode-string',
854'base64-encode-region' and 'base64url-encode-region' no longer accept
855characters in the range U+0080..U+00FF as substitutes for single bytes
856in the range 128..255, but signal an error for all multibyte characters.
857The input must be encoded text.
858
851 859
852* Lisp Changes in Emacs 29.1 860* Lisp Changes in Emacs 29.1
853 861
diff --git a/src/fns.c b/src/fns.c
index 76c76c92ba9..23721334f76 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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