Subject: bug#44411: closed (Re: bug#44411: 28.0.50; uudecode-decode-region-internal is broken)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 07 Nov 2020 09:44:02 +0000

Your bug report

#44411: 28.0.50; uudecode-decode-region-internal is broken

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
44411: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=44411
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#44411: 28.0.50; uudecode-decode-region-internal is broken
From: Eli Zaretskii <[email-masked]>
To: Kazuhiro Ito <[email-masked]>
Cc: [email-masked]
Date: Sat, 07 Nov 2020 11:42:58 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Thu, 05 Nov 2020 19:48:08 +0900
> From: Kazuhiro Ito <[email-masked]>
> Cc: [email-masked]
> 
> > Can you augment your patch along these lines, please?
> 
> Here is a revised one.

Thanks, pushed to the emacs-27 branch.

Since with this patch you have exhausted the amount of changes we can
accept from you without copyright assignment, would you like to start
the assignment process at this time?

Subject: 28.0.50; uudecode-decode-region-internal is broken
From: Kazuhiro Ito <[email-masked]>
To: [email-masked]
Date: Tue, 03 Nov 2020 17:27:41 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

When I call uudecode-decode-region-internal in multibyte buffer, it
fails to decode eight-bit characters.

The function makes string from uuencoded text by passing unsigned char
vlue (0-255) to char-to-string function, which makes multibyte-string.
After that, string is decoded as binary.  But eight-bit characters are
never made in that way.

(let ((ch #xc8))
  (decode-coding-string (char-to-string ch) 'binary))

-> "8"

Additionally, concat and char-to-string functions are called so
frequently that deocder is very slow for large data.

Please see the below patch.

diff --git a/lisp/mail/uudecode.el b/lisp/mail/uudecode.el
index bcbd571b53..f9254aee75 100644
--- a/lisp/mail/uudecode.el
+++ b/lisp/mail/uudecode.el
@@ -149,12 +149,10 @@ uudecode-decode-region-internal
 	      (setq counter (1+ counter)
 		    inputpos (1+ inputpos))
 	      (cond ((= counter 4)
-		     (setq result (cons
-				   (concat
-				    (char-to-string (ash bits -16))
-				    (char-to-string (logand (ash bits -8) 255))
-				    (char-to-string (logand bits 255)))
-				   result))
+		     (setq result (cons (logand bits 255)
+					(cons (logand (ash bits -8) 255)
+					      (cons (ash bits -16)
+						    result))))
 		     (setq bits 0 counter 0))
 		    (t (setq bits (ash bits 6)))))))
 	  (cond
@@ -166,26 +164,21 @@ uudecode-decode-region-internal
 	    ;;(error "uucode ends unexpectedly")
 	    (setq done t))
 	   ((= counter 3)
-	    (setq result (cons
-			  (concat
-			   (char-to-string (logand (ash bits -16) 255))
-			   (char-to-string (logand (ash bits -8) 255)))
-			  result)))
+	    (setq result (cons (logand (ash bits -8) 255)
+			       (cons (logand (ash bits -16) 255)
+				     result))))
 	   ((= counter 2)
-	    (setq result (cons
-			  (char-to-string (logand (ash bits -10) 255))
-			  result))))
+	    (setq result (cons (logand (ash bits -10) 255)
+			       result))))
 	  (skip-chars-forward non-data-chars end))
+	(setq result (apply #'unibyte-string (nreverse result)))
 	(if file-name
             (with-temp-file file-name
               (set-buffer-multibyte nil)
-              (insert (apply #'concat (nreverse result))))
+              (insert result))
 	  (or (markerp end) (setq end (set-marker (make-marker) end)))
 	  (goto-char start)
-	  (if enable-multibyte-characters
-	      (dolist (x (nreverse result))
-                (insert (decode-coding-string x 'binary)))
-	    (insert (apply #'concat (nreverse result))))
+          (insert result)
 	  (delete-region (point) end))))))
 
 ;;;###autoload

-- 
Kazuhiro Ito