all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattias.engdegard@gmail.com>
To: 70988@debbugs.gnu.org
Cc: Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#70988: (read FUNCTION) uses Latin-1 [PATCH]
Date: Thu, 16 May 2024 20:13:18 +0200	[thread overview]
Message-ID: <37B5B5D0-9C0B-4E1C-9F3C-6CA647612E08@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 606 bytes --]

When `read` is called with a function as stream argument, the return values of that function are often interpreted as Latin-1 characters with only the 8 low bits used. Example:

(let* ((next '(?A #x12a nil))
       (f (lambda (&rest args)
            (if args
                (push (car args) next)
              (pop next)))))
  (read f))
=> A*   ; expected: AĪ

This is a result of `readchar` setting *multibyte to 0 on this code path.

The reader is not very consistent: inside string and character literals, the code seems to work as expected.

The fix is straightforward (attached).


[-- Attachment #2: read-from-function.diff --]
[-- Type: application/octet-stream, Size: 1404 bytes --]

diff --git a/src/lread.c b/src/lread.c
index c92b2ede932..2626272c4e2 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -422,6 +422,8 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
       goto read_multibyte;
     }
 
+  if (multibyte)
+    *multibyte = 1;
   tem = call0 (readcharfun);
 
   if (NILP (tem))
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index cc17f7eb3fa..41c9256a9bf 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -387,4 +387,19 @@ lread-skip-to-eof
     (goto-char (point-min))
     (should-error (read (current-buffer)) :type 'end-of-file)))
 
+(ert-deftest lread-from-function ()
+  ;; Test reading from a stream defined by a function.
+  (let ((make-reader (lambda (chars)
+                       (lambda (&rest args)
+                         (if args
+                             (push (car args) chars)
+                           (pop chars))))))
+    (dolist (seq '((?A ?B) (?E ?ä ?ÿ) (?A ?Ω) (?* ?☃) (?a #o303 #o245 ?b)))
+      (let ((str (apply #'string seq)))
+        (should (eq (read (funcall make-reader seq)) (intern str)))
+        (let ((quoted-seq `(?\" ,@seq ?\")))
+          (should (equal (read (funcall make-reader quoted-seq)) str)))))
+    (dolist (c '(?A ?ä ?ÿ ?Ω ?☃))
+      (should (eq (read (funcall make-reader `(?? ,c))) c)))))
+
 ;;; lread-tests.el ends here

             reply	other threads:[~2024-05-16 18:13 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-16 18:13 Mattias Engdegård [this message]
2024-05-16 18:47 ` bug#70988: (read FUNCTION) uses Latin-1 [PATCH] Eli Zaretskii
2024-05-16 19:45   ` Mattias Engdegård
2024-05-16 19:54     ` Eli Zaretskii
2024-05-17  8:08       ` Mattias Engdegård
2024-05-17 10:45         ` Eli Zaretskii
2024-05-17 17:08           ` Mattias Engdegård
2024-05-30 15:43             ` Mattias Engdegård

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=37B5B5D0-9C0B-4E1C-9F3C-6CA647612E08@gmail.com \
    --to=mattias.engdegard@gmail.com \
    --cc=70988@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.