Subject: bug#64733: closed (Re: bug#64733: [PATCH] ; Handle string-at-point at end of buffer gracefully)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 22 Jul 2023 07:22:02 +0000

Your bug report

#64733: [PATCH] ; Handle string-at-point at end of buffer gracefully

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
64733: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64733
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#64733: [PATCH] ; Handle string-at-point at end of buffer gracefully
From: Philip Kaludercic <[email-masked]>
To: Eli Zaretskii <[email-masked]>
Cc: [email-masked]
Date: Sat, 22 Jul 2023 07:21:42 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Eli Zaretskii <[email-masked]> writes:

>> From: Philip Kaludercic <[email-masked]>
>> Cc: [email-masked]
>> Date: Fri, 21 Jul 2023 14:53:14 +0000
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> 
>> > Let's install these on master, and maybe consider backporting then
>> > after Emacs 29.1 is released.
>> 
>> Wasn't the plan to wait for others to comment.
>
> Yes.  I just wanted to make sure we are on the same page regarding
> the branch where to install this.

OK, I've pushed the patches.

Subject: [PATCH] ; Handle string-at-point at end of buffer gracefully
From: Philip Kaludercic <[email-masked]>
To: [email-masked]
Date: Wed, 19 Jul 2023 18:51:05 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

Evaluating (thing-at-point 'string) at the end of a buffer raises an
error:

--8<---------------cut here---------------start------------->8---
Debugger entered--Lisp error: (wrong-type-argument characterp nil)
  char-syntax(nil)
  (eq (char-syntax (char-after)) 34)
  (if (eq (char-syntax (char-after)) 34) (let ((bound (bounds-of-thing-at-point 'sexp))) (and bound (<= (car bound) (point)) (< (point) (cdr bound)) bound)))
  (if (nth 3 ppss) (condition-case nil (progn (goto-char (nth 8 ppss)) (cons (point) (progn (forward-sexp) (point)))) (error nil)) (if (eq (char-syntax (char-after)) 34) (let ((bound (bounds-of-thing-at-point 'sexp))) (and bound (<= (car bound) (point)) (< (point) (cdr bound)) bound))))
  (let ((ppss (syntax-ppss))) (if (nth 3 ppss) (condition-case nil (progn (goto-char (nth 8 ppss)) (cons (point) (progn (forward-sexp) (point)))) (error nil)) (if (eq (char-syntax (char-after)) 34) (let ((bound (bounds-of-thing-at-point 'sexp))) (and bound (<= (car bound) (point)) (< (point) (cdr bound)) bound)))))
  (save-excursion (let ((ppss (syntax-ppss))) (if (nth 3 ppss) (condition-case nil (progn (goto-char (nth 8 ppss)) (cons (point) (progn (forward-sexp) (point)))) (error nil)) (if (eq (char-syntax (char-after)) 34) (let ((bound (bounds-of-thing-at-point ...))) (and bound (<= (car bound) (point)) (< (point) (cdr bound)) bound))))))
  thing-at-point-bounds-of-string-at-point()
  funcall(thing-at-point-bounds-of-string-at-point)
  (cond ((get thing 'bounds-of-thing-at-point) (funcall (get thing 'bounds-of-thing-at-point))) ((and (not (eq thing 'whitespace)) (save-excursion (goto-char (point-min)) (not (re-search-forward "[^\11\n ]" nil t)))) nil) (t (let ((orig (point))) (condition-case nil (progn (save-excursion (funcall (or ... ...)) (funcall (or ... ...)) (let (...) (if ... ... ... ... ... ...)))) (error nil)))))
  bounds-of-thing-at-point(string)
  (let ((bounds (bounds-of-thing-at-point thing))) (if bounds (progn (buffer-substring (car bounds) (cdr bounds)))))
  (cond ((let* ((--cl-var-- thing-at-point-provider-alist) #'nil (pthing nil) (result nil) (--cl-var-- t) (--cl-var-- t) --cl-var--) (while (and (consp --cl-var--) (progn (progn (setq function ...) (setq pthing ...)) (if (eq pthing thing) (progn ...)) (if result (progn ... ...) t))) (setq --cl-var-- (cdr --cl-var--)) (setq --cl-var-- nil)) --cl-var--)) ((get thing 'thing-at-point) (funcall (get thing 'thing-at-point))) (t (let ((bounds (bounds-of-thing-at-point thing))) (if bounds (progn (buffer-substring (car bounds) (cdr bounds)))))))
  (let ((text (cond ((let* ((--cl-var-- thing-at-point-provider-alist) #'nil (pthing nil) (result nil) (--cl-var-- t) (--cl-var-- t) --cl-var--) (while (and ... ...) (setq --cl-var-- ...) (setq --cl-var-- nil)) --cl-var--)) ((get thing 'thing-at-point) (funcall (get thing 'thing-at-point))) (t (let ((bounds ...)) (if bounds (progn ...))))))) (if (and text no-properties (sequencep text)) (progn (set-text-properties 0 (length text) nil text))) text)
  thing-at-point(string)
  eval-expression((thing-at-point 'string) nil nil 127)
  funcall-interactively(eval-expression (thing-at-point 'string) nil nil 127)
  command-execute(eval-expression)
--8<---------------cut here---------------end--------------->8---

In this case it is easy to avoid it, with the below patch, by ensuring
that `char-syntax' is not passed a nil.

In GNU Emacs 29.0.92 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.37, cairo version 1.16.0) of 2023-07-16 built on quetzal
Repository revision: fcde115d5748880ad7ebbf43a10753fb7014a6e1
Repository branch: emacs-29
System Description: Debian GNU/Linux 12 (bookworm)

Configured using:
 'configure --with-pgtk --with-native-compilation --with-imagemagick
 --with-tree-sitter'

>From fb5da3b4a4785938d82c8ce4ea59215a8905ddd7 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <[email-masked]>
Date: Wed, 19 Jul 2023 20:49:30 +0200
Subject: [PATCH] ; Handle string-at-point at end of buffer gracefully

* lisp/thingatpt.el (thing-at-point-bounds-of-string-at-point): Check
if 'char-after' returns non-nil before passing it to 'char-syntax'.
---
 lisp/thingatpt.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 9363a474cb5..46e700c2091 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -250,7 +250,7 @@ thing-at-point-bounds-of-string-at-point
             (goto-char (nth 8 ppss))
             (cons (point) (progn (forward-sexp) (point))))
         ;; At the beginning of the string
-        (if (eq (char-syntax (char-after)) ?\")
+        (if (and (char-after) (eq (char-syntax (char-after)) ?\"))
             (let ((bound (bounds-of-thing-at-point 'sexp)))
 	      (and bound
 	           (<= (car bound) (point)) (< (point) (cdr bound))
-- 
2.39.2