From 8ad9fce0f469cecd4d4b682c25272348f35259b2 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 25 May 2026 07:38:30 -0500 Subject: fix: guard issue async callbacks against a killed buffer pearl--push-issue-field (the field setters) and pearl-refresh-current-issue ran goto-char on the captured marker in their success callbacks with no liveness check. If the buffer was killed before the async response returned, the dead marker signaled "Marker does not point anywhere" from the callback. I wrapped the buffer work in a buffer-live-p check; the field setters still report the remote success, and refresh reports that the buffer was closed. This closes the last gap in the command/context test-coverage task. The other seven items it named were already covered by the quick-bug batch's tests; this adds the killed-buffer regression for the issue paths (delete-current-comment already had its own). --- tests/test-pearl-bugfixes.el | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'tests') diff --git a/tests/test-pearl-bugfixes.el b/tests/test-pearl-bugfixes.el index 7f5c635..caab884 100644 --- a/tests/test-pearl-bugfixes.el +++ b/tests/test-pearl-bugfixes.el @@ -151,5 +151,30 @@ (should-error (pearl-run-saved-query "bad") :type 'user-error) (should-not fetched)))) +;;; Bug: async issue callbacks must be harmless if the buffer is killed + +(ert-deftest test-pearl-push-issue-field-killed-buffer-no-signal () + "A field push whose buffer is killed before the success callback does not signal." + (let ((buf (generate-new-buffer "pearl-pif-kill"))) + (unwind-protect + (let (marker) + (with-current-buffer buf + (insert "* h\n:PROPERTIES:\n:LINEAR-ID: a\n:END:\nbody\n") + (org-mode) + (goto-char (point-min)) + (setq marker (point-marker))) + ;; The update stub kills the buffer, then reports success; the success + ;; callback must not run its buffer ops (or signal) on a dead buffer. + (cl-letf (((symbol-function 'pearl--update-issue-async) + (lambda (_id _fields cb) (kill-buffer buf) (funcall cb '(:success t))))) + ;; Must complete without signaling; the on-success thunk (which would + ;; error) must not run because the buffer is dead. + (pearl--push-issue-field + "a" marker '(("priority" . 2)) + (lambda () (error "on-success must not run against a dead buffer")) + "ok" "fail") + (should-not (buffer-live-p buf)))) + (when (buffer-live-p buf) (kill-buffer buf))))) + (provide 'test-pearl-bugfixes) ;;; test-pearl-bugfixes.el ends here -- cgit v1.2.3