Subject: Re: [PATCH] Fix two bugs in removing bookmark fringe marks (bug#70019)

From: Karl Fogel <[email-masked]>
Date: Fri, 19 Apr 2024 19:54:02 -0500

On 19 Apr 2024, Dani Moncayo wrote:
>I've applied the patch to my source tree and re-made my 
>out-of-tree build.
>But I still see the same problems reported in this bug ticket.
>Maybe I've made some mistake... ¿Don't you see the problems with 
>the
>patch applied?

Nope, you didn't make any mistake.  I see the problem; please try 
this revised version, and thank you for testing.

Best regards,
-Karl

>From 705eeb968c85cf8d865c893778cc0df6a6db6034 Mon Sep 17 00:00:00 2001
From: Karl Fogel <[email-masked]>
Date: Thu, 18 Apr 2024 23:49:29 -0500
Subject: [PATCH] Fix two bugs in removing bookmark fringe marks

This fixes bug#70019 and a separate fringe-mark removal bug that
also affected bookmarks in certain Info nodes.

* lisp/bookmark.el (bookmark--remove-fringe-mark): Fix bug#70019 by
temporarily widening in order to ensure we fetch the right overlays.
Also, normalize both filenames before comparing, to avoid spurious
failure to match.
---
 lisp/bookmark.el | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index bf2357207d8..06f8e24b518 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -515,18 +515,45 @@ bookmark--remove-fringe-mark
         (non-essential t)
         overlays found temp)
     (when (and pos filename)
-      (setq filename (abbreviate-file-name (expand-file-name filename)))
       (dolist (buf (buffer-list))
         (with-current-buffer buf
-          (when (equal filename
-                       (ignore-errors (bookmark-buffer-file-name)))
-            (setq overlays
-                  (save-excursion
-                    (goto-char pos)
-                    (overlays-in (pos-bol) (1+ (pos-bol)))))
-            (while (and (not found) (setq temp (pop overlays)))
-              (when (eq 'bookmark (overlay-get temp 'category))
-                (delete-overlay (setq found temp))))))))))
+          (let ((bkmk-fname (ignore-errors (bookmark-buffer-file-name))))
+            (when bkmk-fname
+              ;; Normalize both filenames before comparing, because the
+              ;; filename we receive from the bookmark wasn't
+              ;; necessarily generated by `bookmark-buffer-file-name'.
+              ;; For example, bookmarks set in Info nodes get a filename
+              ;; based on `Info-current-file', and under certain
+              ;; circumstances that can be an unexpanded path (e.g.,
+              ;; when the Info page was under your home directory).
+              (let ((this-fname-normalized (expand-file-name filename))
+                    (bkmk-fname-normalized (expand-file-name bkmk-fname)))
+                (when (equal this-fname-normalized bkmk-fname-normalized)
+                  (setq overlays
+                        (save-excursion
+                          (save-restriction
+                            ;; Suppose bookmark "foo" was earlier set at
+                            ;; location X in a file, but now the file is
+                            ;; narrowed such that X is outside the
+                            ;; restriction.  Then the `goto-char' below
+                            ;; would go to the wrong place and thus the
+                            ;; wrong overlays would be fetched.  This is
+                            ;; why we temporarily `widen' before
+                            ;; fetching.
+                            ;;
+                            ;; (This circumstance can easily arise when
+                            ;; a bookmark was set on Info node X but now
+                            ;; the "*info*" buffer is showing some other
+                            ;; node Y, with X and Y physically located
+                            ;; in the same file, as is often the case
+                            ;; with Info nodes.  See bug #70019, for
+                            ;; example.)
+                            (widen)
+                            (goto-char pos)
+                            (overlays-in (pos-bol) (1+ (pos-bol))))))
+                  (while (and (not found) (setq temp (pop overlays)))
+                    (when (eq 'bookmark (overlay-get temp 'category))
+                      (delete-overlay (setq found temp)))))))))))))
 
 (defun bookmark-maybe-sort-alist ()
   "Return `bookmark-alist' for display.
-- 
2.43.0