From 49f673be2c49f436440bf74a4aac5f08f2ae9239 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 15 Apr 2024 15:53:48 -0400 Subject: [PATCH] (track-changes--before): Fix bug#70396 * lisp/emacs-lisp/track-changes.el (track-changes--before): Widen the buffer before accessing it with positions potentially outside the beg..end region. (cherry picked from commit 5fda398fb3bbda43dab37a0c187c90ad4bc4d1b0) --- lisp/emacs-lisp/track-changes.el | 68 ++++++++++++++++---------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/lisp/emacs-lisp/track-changes.el b/lisp/emacs-lisp/track-changes.el index 1bab7ca38fd..df4aad0d596 100644 --- a/lisp/emacs-lisp/track-changes.el +++ b/lisp/emacs-lisp/track-changes.el @@ -481,42 +481,42 @@ Details logged to `track-changes--error-log'") (funcall signal-if-disjoint end track-changes--before-beg) (funcall signal-if-disjoint track-changes--before-end beg))) (funcall reset)) - (cl-assert (save-restriction - (widen) - (<= (point-min) + (save-restriction + (widen) + (cl-assert (<= (point-min) track-changes--before-beg track-changes--before-end - (point-max)))) - (when (< beg track-changes--before-beg) - (if (and track-changes--disjoint-trackers - (funcall signal-if-disjoint end track-changes--before-beg)) - (funcall reset) - (let* ((old-bbeg track-changes--before-beg) - ;; To avoid O(N²) behavior when faced with many small changes, - ;; we copy more than needed. - (new-bbeg (min (max (point-min) - (- old-bbeg - (length track-changes--before-string))) - beg))) - (setf track-changes--before-beg new-bbeg) - (cl-callf (lambda (old new) (concat new old)) - track-changes--before-string - (buffer-substring-no-properties new-bbeg old-bbeg))))) - - (when (< track-changes--before-end end) - (if (and track-changes--disjoint-trackers - (funcall signal-if-disjoint track-changes--before-end beg)) - (funcall reset) - (let* ((old-bend track-changes--before-end) - ;; To avoid O(N²) behavior when faced with many small changes, - ;; we copy more than needed. - (new-bend (max (min (point-max) - (+ old-bend - (length track-changes--before-string))) - end))) - (setf track-changes--before-end new-bend) - (cl-callf concat track-changes--before-string - (buffer-substring-no-properties old-bend new-bend)))))))) + (point-max))) + (when (< beg track-changes--before-beg) + (if (and track-changes--disjoint-trackers + (funcall signal-if-disjoint end track-changes--before-beg)) + (funcall reset) + (let* ((old-bbeg track-changes--before-beg) + ;; To avoid O(N²) behavior when faced with many small + ;; changes, we copy more than needed. + (new-bbeg + (min beg (max (point-min) + (- old-bbeg + (length track-changes--before-string)))))) + (setf track-changes--before-beg new-bbeg) + (cl-callf (lambda (old new) (concat new old)) + track-changes--before-string + (buffer-substring-no-properties new-bbeg old-bbeg))))) + + (when (< track-changes--before-end end) + (if (and track-changes--disjoint-trackers + (funcall signal-if-disjoint track-changes--before-end beg)) + (funcall reset) + (let* ((old-bend track-changes--before-end) + ;; To avoid O(N²) behavior when faced with many small + ;; changes, we copy more than needed. + (new-bend + (max end (min (point-max) + (+ old-bend + (length track-changes--before-string)))))) + (setf track-changes--before-end new-bend) + (cl-callf concat track-changes--before-string + (buffer-substring-no-properties old-bend new-bend))))))))) (defun track-changes--after (beg end len) (cl-assert track-changes--state) -- 2.39.5