From 514c53e2b34873142eea88c09d566064f16b6fbb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Wed, 8 May 2024 12:13:48 +0200 Subject: [PATCH] Don't mutate strings in cl-substitute This fixes cl-substitute, cl-substitute-if, cl-substitute-if-not, cl-nsubstitute, cl-nsubstitute-if and cl-nsubstitute-if-not, when called with a string sequence argument. * lisp/emacs-lisp/cl-seq.el (cl-nsubstitute): Avoid running in O(n^2) time and make future-safe. (cherry picked from commit de5a89254cb8645143e9f4e51a1727a7237109e8) --- lisp/emacs-lisp/cl-seq.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/emacs-lisp/cl-seq.el b/lisp/emacs-lisp/cl-seq.el index e46955fd968..42f54603899 100644 --- a/lisp/emacs-lisp/cl-seq.el +++ b/lisp/emacs-lisp/cl-seq.el @@ -452,14 +452,15 @@ to avoid corrupting the original SEQ. (apply 'cl-substitute cl-new nil cl-list :if-not cl-pred cl-keys)) ;;;###autoload -(defun cl-nsubstitute (cl-new cl-old cl-seq &rest cl-keys) +(defun cl-nsubstitute (cl-new cl-old seq &rest cl-keys) "Substitute NEW for OLD in SEQ. This is a destructive function; it reuses the storage of SEQ whenever possible. \nKeywords supported: :test :test-not :key :count :start :end :from-end \n(fn NEW OLD SEQ [KEYWORD VALUE]...)" (cl--parsing-keywords (:test :test-not :key :if :if-not :count (:start 0) :end :from-end) () - (let ((len (length cl-seq))) + (let* ((cl-seq (if (stringp seq) (string-to-vector seq) seq)) + (len (length cl-seq))) (or (eq cl-old cl-new) (<= (or cl-count (setq cl-count len)) 0) (if (and (listp cl-seq) (or (not cl-from-end) (> cl-count (/ len 2)))) (let ((cl-p (nthcdr cl-start cl-seq))) @@ -483,8 +484,8 @@ This is a destructive function; it reuses the storage of SEQ whenever possible. (progn (aset cl-seq cl-start cl-new) (setq cl-count (1- cl-count)))) - (setq cl-start (1+ cl-start))))))) - cl-seq)) + (setq cl-start (1+ cl-start)))))) + (if (stringp seq) (concat cl-seq) cl-seq)))) ;;;###autoload (defun cl-nsubstitute-if (cl-new cl-pred cl-list &rest cl-keys) -- 2.39.5