From 7f9ad5980ce2e998ef57a95c2283d1a87d5613d1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Fri, 25 Sep 2020 01:53:07 +0200 Subject: [PATCH] Fix replace-in-string multibyteness problems with string-search * lisp/subr.el (replace-in-string): Simplify by using the new string-search function (bug#43598). --- lisp/subr.el | 43 ++++++++++++----------------------------- test/lisp/subr-tests.el | 10 +++++++++- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/lisp/subr.el b/lisp/subr.el index 377d914718a..0f72b382fe8 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4430,37 +4430,18 @@ Unless optional argument INPLACE is non-nil, return a new string." newstr)) (defun replace-in-string (fromstring tostring instring) - "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs. -This function returns a freshly created string." - (declare (side-effect-free t)) - (let ((i 0) - (start 0) - (result nil)) - (while (< i (length instring)) - (if (eq (aref instring i) - (aref fromstring 0)) - ;; See if we're in a match. - (let ((ii i) - (if 0)) - (while (and (< ii (length instring)) - (< if (length fromstring)) - (eq (aref instring ii) - (aref fromstring if))) - (setq ii (1+ ii) - if (1+ if))) - (if (not (= if (length fromstring))) - ;; We didn't have a match after all. - (setq i (1+ i)) - ;; We had one, so gather the previous part and the - ;; substitution. - (when (not (= start i)) - (push (substring instring start i) result)) - (push tostring result) - (setq i ii - start ii))) - (setq i (1+ i)))) - (when (not (= start i)) - (push (substring instring start i) result)) + "Replace FROMSTRING with TOSTRING in INSTRING each time it occurs." + (declare (pure t)) + (let ((start 0) + (result nil) + pos) + (while (setq pos (string-search fromstring instring start)) + (unless (= start pos) + (push (substring instring start pos) result)) + (push tostring result) + (setq start (+ start (length fromstring)))) + (unless (= start pos) + (push (substring instring start pos) result)) (apply #'concat (nreverse result)))) (defun replace-regexp-in-string (regexp rep string &optional diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 2adb4a62e86..14870d4adab 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -456,7 +456,15 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (equal (replace-in-string "azot" "bar" "zat") "zat")) (should (equal (replace-in-string "azot" "bar" "azot") - "bar"))) + "bar")) + + (should (equal (replace-in-string "azot" "bar" "foozotbar") + "foozotbar")) + + (should (equal (replace-in-string "\377" "x" "a\377b") + "axxb")) + (should (equal (replace-in-string "\377" "x" "a\377ø") + "axxø"))) (provide 'subr-tests) ;;; subr-tests.el ends here -- 2.39.5