From f535c0e49d5e629e60eabe9097b9c674783f9674 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 25 May 2023 22:28:25 +0200 Subject: [PATCH] Handle #@00 in new reader in a compatible way (bug#63722) This was a regression from Emacs 28. * src/lread.c (skip_lazy_string, read0): Make #@00 read as nil, which is a quirk from the old reader that we preserve for compatibility. * test/src/lread-tests.el (lread-skip-to-eof): Verify it. Reported by Richard Newton. --- src/lread.c | 17 +++++++++++------ test/src/lread-tests.el | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/lread.c b/src/lread.c index 342d367d985..29321263af3 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3400,8 +3400,9 @@ read_bool_vector (Lisp_Object readcharfun) } /* Skip (and optionally remember) a lazily-loaded string - preceded by "#@". */ -static void + preceded by "#@". Return true if this was a normal skip, + false if we read #@00 (which skips to EOF). */ +static bool skip_lazy_string (Lisp_Object readcharfun) { ptrdiff_t nskip = 0; @@ -3427,9 +3428,9 @@ skip_lazy_string (Lisp_Object readcharfun) digits++; if (digits == 2 && nskip == 0) { - /* #@00 means "skip to end" */ + /* #@00 means "read nil and skip to end" */ skip_dyn_eof (readcharfun); - return; + return false; } } @@ -3476,6 +3477,8 @@ skip_lazy_string (Lisp_Object readcharfun) else /* Skip that many bytes. */ skip_dyn_bytes (readcharfun, nskip); + + return true; } /* Given a lazy-loaded string designator VAL, return the actual string. @@ -3933,8 +3936,10 @@ read0 (Lisp_Object readcharfun, bool locate_syms) /* #@NUMBER is used to skip NUMBER following bytes. That's used in .elc files to skip over doc strings and function definitions that can be loaded lazily. */ - skip_lazy_string (readcharfun); - goto read_obj; + if (skip_lazy_string (readcharfun)) + goto read_obj; + obj = Qnil; /* #@00 skips to EOF and yields nil. */ + break; case '$': /* #$ -- reference to lazy-loaded string */ diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el index 459a06a39b6..7d885abf364 100644 --- a/test/src/lread-tests.el +++ b/test/src/lread-tests.el @@ -339,4 +339,20 @@ literals (Bug#20852)." (should (byte-code-function-p f)) (should (equal (aref f 4) "My little\ndoc string\nhere")))))) +(ert-deftest lread-skip-to-eof () + ;; Check the special #@00 syntax that, for compatibility, reads as + ;; nil while absorbing the remainder of the input. + (with-temp-buffer + (insert "#@00 and the rest\n" + "should be ignored) entirely\n") + (goto-char (point-min)) + (should (equal (read (current-buffer)) nil)) + (should (eobp)) + ;; Add an unbalanced bracket to the beginning and try again; + ;; we should get an error. + (goto-char (point-min)) + (insert "( ") + (goto-char (point-min)) + (should-error (read (current-buffer)) :type 'end-of-file))) + ;;; lread-tests.el ends here -- 2.39.2