Received: (at 78590) by debbugs.gnu.org; 28 May 2025 11:24:49 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Wed May 28 07:24:49 2025 Received: from localhost ([127.0.0.1]:51542 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uKEtt-0000FV-0b for submit <at> debbugs.gnu.org; Wed, 28 May 2025 07:24:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50612) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1uKEtr-0000FG-H2 for 78590 <at> debbugs.gnu.org; Wed, 28 May 2025 07:24:48 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <eliz@HIDDEN>) id 1uKEtl-0004Hf-Fq; Wed, 28 May 2025 07:24:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=ZF+jwgg+huFcZ3gCJZGJjqkZI3n9fdeVE5RH0ackJzI=; b=PnwohCCsnq10 Ru+Dplugfib4QOUS2mBoMU4I7zFxEEWCJy4bNC16zspR6nL2MD5/UMTJrdUJDaA9Rz7W/xOucWmO0 nbh5yS4Ku2m32/Y9E26wf5w05ZeuN2+u1hnoVNdXwkRVWevj3phWfm3zDt1CrXSHiqf2dIjd34eJ1 T+qLH2PuM0FIQJqA/eZdhBFFlqnFrVu1cJCfT0aEekw21vSPMVVjcxv+giqIE1xpSdMzWpn713j2Z B5xsS/SpLS6beMmuLWA53Sm6Sr8GhfIfensljqvz0irJJuVsU6oEvDwDs0U2GNfO4tEdTPrplY01l lVEN9X+iXVRcNy2SOqVljQ==; Date: Wed, 28 May 2025 14:24:38 +0300 Message-Id: <86sekpvuyx.fsf@HIDDEN> From: Eli Zaretskii <eliz@HIDDEN> To: Pip Cet <pipcet@HIDDEN> In-Reply-To: <87ikll7uyr.fsf@HIDDEN> (message from Pip Cet on Tue, 27 May 2025 18:46:24 +0000) Subject: Re: bug#78590: 31.0.50; print_object calls strout unsafely References: <8734cra4x7.fsf@HIDDEN> <87h6178d6w.fsf@HIDDEN> <86r00bxl71.fsf@HIDDEN> <87sekq6iba.fsf@HIDDEN> <861ps9ykm8.fsf@HIDDEN> <87ikll7uyr.fsf@HIDDEN> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 78590 Cc: 78590 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -3.3 (---) > Date: Tue, 27 May 2025 18:46:24 +0000 > From: Pip Cet <pipcet@HIDDEN> > Cc: 78590 <at> debbugs.gnu.org > > "Eli Zaretskii" <eliz@HIDDEN> writes: > > >> How about calling Fmapc (printcharfun, string) at that point, from > >> print_string? > > > > If that works, fine. But didn't you say below that print_string does > > something we don't want to do in this case? Or am I misunderstanding > > what you mean? > > Sorry, that wasn't quite clear. I also forgot to include the proposed > patch: Ah, okay, there was indeed an misunderstanding, see below. > else > { > - /* Otherwise, string may be relocated by printing one char. > - So re-fetch the string address for each character. */ > - ptrdiff_t i; > - ptrdiff_t size = SCHARS (string); > - ptrdiff_t size_byte = SBYTES (string); > - if (size == size_byte) > - for (i = 0; i < size; i++) > - printchar (SREF (string, i), printcharfun); > - else > - for (i = 0; i < size_byte; ) > - { > - /* Here, we must convert each multi-byte form to the > - corresponding character code before handing it to PRINTCHAR. */ > - int len, ch = string_char_and_length (SDATA (string) + i, &len); > - printchar (ch, printcharfun); > - i += len; > - } > + /* printcharfun is a Lisp function. */ > + Fmapc (printcharfun, string); What is the rationale for calling Fmapc here? Doesn't it do in this case what the original code did, but at a price of two additional levels of function calls? IOW, why did you want to get rid of the original code above? I have no other issues with your suggested patch.
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at 78590) by debbugs.gnu.org; 27 May 2025 18:46:40 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue May 27 14:46:40 2025 Received: from localhost ([127.0.0.1]:44175 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJzJv-00021F-L7 for submit <at> debbugs.gnu.org; Tue, 27 May 2025 14:46:40 -0400 Received: from mail-4316.protonmail.ch ([185.70.43.16]:14923) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <pipcet@HIDDEN>) id 1uJzJs-00020c-Ms for 78590 <at> debbugs.gnu.org; Tue, 27 May 2025 14:46:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1748371589; x=1748630789; bh=PK87D/tLEqI5y7H8dmfkOamlXdihVzU8T5AgJxEaOs0=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=q5DaOsMT13paOfR6THgY/687ui2I6nDJ+Z06t7736KRV50AHo9D4wRk6bcjlM3+7i w6VnoA8LisKfcxdGZ4Rg+xxuVIu6wky0ulNZhSiytwFtN6Qsy+oVWbQ2HdBy9J4Nnz PDkWGpnchw1VnY3MyD8RTONvOTKUQ+HXVq0BdDtu9f9XfCg99sig/BGvs3cI6oaXL3 hWIUcmR+RrNm4E49+PDXlsetz3uk97urHweA78PUzQvtocdLEpywGZlxnnvbf3D5oB PJvyM2jIinc1SpbDuUgIGH1ydsdZIKwVXmHFxpr6kOrOvEVkbt2InJiHLhCBqkCWMT HmuWhkem7TfqQ== Date: Tue, 27 May 2025 18:46:24 +0000 To: Eli Zaretskii <eliz@HIDDEN> From: Pip Cet <pipcet@HIDDEN> Subject: Re: bug#78590: 31.0.50; print_object calls strout unsafely Message-ID: <87ikll7uyr.fsf@HIDDEN> In-Reply-To: <861ps9ykm8.fsf@HIDDEN> References: <8734cra4x7.fsf@HIDDEN> <87h6178d6w.fsf@HIDDEN> <86r00bxl71.fsf@HIDDEN> <87sekq6iba.fsf@HIDDEN> <861ps9ykm8.fsf@HIDDEN> Feedback-ID: 112775352:user:proton X-Pm-Message-ID: f26c6b96edce2a365f9eb442d896d4dca34c9d24 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 78590 Cc: 78590 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) "Eli Zaretskii" <eliz@HIDDEN> writes: >> Date: Tue, 27 May 2025 18:05:00 +0000 >> From: Pip Cet <pipcet@HIDDEN> >> Cc: 78590 <at> debbugs.gnu.org >> >> "Eli Zaretskii" <eliz@HIDDEN> writes: >> >> > I agree that the current code is buggy because it keeps referencing a >> > Lisp string's data via a 'char *' pointer while calling a Lisp >> > function PRINTCHARFUN. >> >> How about calling Fmapc (printcharfun, string) at that point, from >> print_string? > > If that works, fine. But didn't you say below that print_string does > something we don't want to do in this case? Or am I misunderstanding > what you mean? Sorry, that wasn't quite clear. I also forgot to include the proposed patch: From 43a27ab64584d98cf10a3f1616701ceae0cdb510 Mon Sep 17 00:00:00 2001 From: Pip Cet <pipcet@HIDDEN> Subject: [PATCH 1/2] Fix unsafe SDATA usage in print.c (bug#78590) * src/print.c (print_string_1): Renamed from 'print_string', with an extra argument to disable nonascii escaping. Call 'Fmapc' when passed a Lisp function. (print_string): New function. (print_object): Use 'print_string_1', not 'strout'. --- src/print.c | 33 ++++++++++++--------------------- test/src/print-tests.el | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/print.c b/src/print.c index b17ec337f70..cd8316a4048 100644 --- a/src/print.c +++ b/src/print.c @@ -469,18 +469,18 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t si= ze_byte, because printing one char can relocate. */ =20 static void -print_string (Lisp_Object string, Lisp_Object printcharfun) +print_string_1 (Lisp_Object string, Lisp_Object printcharfun, bool escape_= nonascii) { if (EQ (printcharfun, Qt) || NILP (printcharfun)) { ptrdiff_t chars; =20 - if (print_escape_nonascii) + if (escape_nonascii) =09string =3D string_escape_byte8 (string); =20 if (STRING_MULTIBYTE (string)) =09chars =3D SCHARS (string); - else if (! print_escape_nonascii + else if (! escape_nonascii =09 && (EQ (printcharfun, Qt) =09=09 ? ! NILP (BVAR (&buffer_defaults, enable_multibyte_characters)) =09=09 : ! NILP (BVAR (current_buffer, enable_multibyte_characters)))) @@ -524,25 +524,16 @@ print_string (Lisp_Object string, Lisp_Object printch= arfun) } else { - /* Otherwise, string may be relocated by printing one char. -=09 So re-fetch the string address for each character. */ - ptrdiff_t i; - ptrdiff_t size =3D SCHARS (string); - ptrdiff_t size_byte =3D SBYTES (string); - if (size =3D=3D size_byte) -=09for (i =3D 0; i < size; i++) -=09 printchar (SREF (string, i), printcharfun); - else -=09for (i =3D 0; i < size_byte; ) -=09 { -=09 /* Here, we must convert each multi-byte form to the -=09 corresponding character code before handing it to PRINTCHAR. */ -=09 int len, ch =3D string_char_and_length (SDATA (string) + i, &len); -=09 printchar (ch, printcharfun); -=09 i +=3D len; -=09 } + /* printcharfun is a Lisp function. */ + Fmapc (printcharfun, string); } } + +static void +print_string (Lisp_Object string, Lisp_Object printcharfun) +{ + print_string_1 (string, printcharfun, print_escape_nonascii); +} =0C DEFUN ("write-char", Fwrite_char, Swrite_char, 1, 2, 0, doc: /* Output character CHARACTER to stream PRINTCHARFUN. @@ -2282,7 +2273,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharf= un, bool escapeflag) =09} else if (STRINGP (num)) =09{ -=09 strout (SSDATA (num), SCHARS (num), SBYTES (num), printcharfun); +=09 print_string_1 (num, printcharfun, false); =09 goto next_obj; =09} } diff --git a/test/src/print-tests.el b/test/src/print-tests.el index af57311135b..036248fd091 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el @@ -540,5 +540,23 @@ test-print-unreadable-function-buffer (should (eq callback-buffer buffer)) (should (equal str "tata")))) =20 +(ert-deftest test-print-number-realloc () + ;; Test for bug#78590. Note that this may in rare cases crash unfixed + ;; Emacs versions. + (let ((print-circle t) + (print-number-table (make-hash-table)) + (print-continuous-numbering t) + (str "yy") + (outstr "")) + (garbage-collect) + (ignore (make-string 100 ?a)) + (puthash str (make-string 3 ?x) print-number-table) + (prin1 str + (lambda (c) + (setq outstr (concat outstr (string c))) + (garbage-collect) + (ignore (make-string 100 ?b)))) + (should (equal outstr "xxx")))) + (provide 'print-tests) ;;; print-tests.el ends here --=20 2.48.1 >> It does, however, also transform the string by escaping some characters, >> which seems incorrect to me in these circumstances (and would mean >> changing existing behavior). > > So calling print_string as it is will not do what we want, right? The new function print_string_1 has an extra flag parameter; all existing callers set it to print_escape_nonascii by calling print_string as before, the new caller directly calls print_string_1 and forcibly disables byte8 escaping (and enables multibyte conversion where necessary). >> > If this requires adding an additional argument to strout, to pass the >> > Lisp string, which will be used only in the last 'else' clause there, >> > that's not difficult, right? >> >> But we already have print_string, which does almost exactly that, right? >> All it needs is an extra argument to avoid the byte8 escaping (unless >> I'm wrong and we actually want that to happen to our string here). > > Sure, that works as well, I think (though I took only a cursory look > at print_string, so maybe I missed something). > > The important part, I think, is to avoid duplicating the string if we > can avoid that. I believe you're right. (It's probably okay to copy strings when printcharfun is Qt, redisplay will be much slower than creating the copy, but when output isn't for the echo area there's no reason to believe the replacement strings are short). Pip
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at 78590) by debbugs.gnu.org; 27 May 2025 18:28:13 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue May 27 14:28:13 2025 Received: from localhost ([127.0.0.1]:44063 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJz24-0000aH-F3 for submit <at> debbugs.gnu.org; Tue, 27 May 2025 14:28:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35006) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1uJz1t-0000Z6-Oz for 78590 <at> debbugs.gnu.org; Tue, 27 May 2025 14:28:09 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <eliz@HIDDEN>) id 1uJz1m-0000gP-AZ; Tue, 27 May 2025 14:27:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=SnhUTVJxFPMa+esolW3IAJKFU3EVeZOMnuPVk2Kg93k=; b=bUtCKKuIdT9y fj2ma7KNIjjaHXxg/QY1EPD/ePFS0DLDFUc7/LW24fBPeyq4agF2TGuf0g09Zuyt7TIF3Yi5DLm+w AwcFvEc9TZfzPAUW06czcUspSZtiZOkcWAQ1Hg6aWnfxZE9EQokVzeqGoWvvNnBCqaqH0y4+Dr4/N gnz8akUXFTHSaxoY5lnsU/XH6RjHtlUNhBlhe5ZEaufpPIMYj9Oy2yfgXs9p4QDbf2OoIsIZgIzYL 4mlgN7S5ff3UDhw4e+8CuMwfQAjupGDcxX6deuYdSQpqBGnbX9jX7J17HfGRyki4Ao00PVp9WSv4j 7T6U4VS3WUm9K776Zdbi1g==; Date: Tue, 27 May 2025 21:27:43 +0300 Message-Id: <861ps9ykm8.fsf@HIDDEN> From: Eli Zaretskii <eliz@HIDDEN> To: Pip Cet <pipcet@HIDDEN> In-Reply-To: <87sekq6iba.fsf@HIDDEN> (message from Pip Cet on Tue, 27 May 2025 18:05:00 +0000) Subject: Re: bug#78590: 31.0.50; print_object calls strout unsafely References: <8734cra4x7.fsf@HIDDEN> <87h6178d6w.fsf@HIDDEN> <86r00bxl71.fsf@HIDDEN> <87sekq6iba.fsf@HIDDEN> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 78590 Cc: 78590 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -3.3 (---) > Date: Tue, 27 May 2025 18:05:00 +0000 > From: Pip Cet <pipcet@HIDDEN> > Cc: 78590 <at> debbugs.gnu.org > > "Eli Zaretskii" <eliz@HIDDEN> writes: > > > I agree that the current code is buggy because it keeps referencing a > > Lisp string's data via a 'char *' pointer while calling a Lisp > > function PRINTCHARFUN. > > How about calling Fmapc (printcharfun, string) at that point, from > print_string? If that works, fine. But didn't you say below that print_string does something we don't want to do in this case? Or am I misunderstanding what you mean? > > int len, ch = (string_char_and_length > > ((const unsigned char *) ptr + i, &len)); > > use > > > > int len, ch = (string_char_and_length > > (SDATA (string) + i, &len)); > > > > where 'string' is the original Lisp string to print? > > That's what print_string does (even though it should be more careful, > which is most easily achieved by delegating to Fmapc and fixing that). Yes. > It does, however, also transform the string by escaping some characters, > which seems incorrect to me in these circumstances (and would mean > changing existing behavior). So calling print_string as it is will not do what we want, right? > > If this requires adding an additional argument to strout, to pass the > > Lisp string, which will be used only in the last 'else' clause there, > > that's not difficult, right? > > But we already have print_string, which does almost exactly that, right? > All it needs is an extra argument to avoid the byte8 escaping (unless > I'm wrong and we actually want that to happen to our string here). Sure, that works as well, I think (though I took only a cursory look at print_string, so maybe I missed something). The important part, I think, is to avoid duplicating the string if we can avoid that.
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at 78590) by debbugs.gnu.org; 27 May 2025 18:05:30 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue May 27 14:05:30 2025 Received: from localhost ([127.0.0.1]:43839 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJyg3-00077y-AX for submit <at> debbugs.gnu.org; Tue, 27 May 2025 14:05:30 -0400 Received: from mail-10629.protonmail.ch ([79.135.106.29]:54875) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <pipcet@HIDDEN>) id 1uJyfo-00070u-UB for 78590 <at> debbugs.gnu.org; Tue, 27 May 2025 14:05:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1748369104; x=1748628304; bh=noZOQbPlbzPtJIGeUzW82ImNsRqUNTE1uOL76ygs79k=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=GCMAhx5Q9A8wyQ33qG3uaPHqv7p0YB/EZkHziRJ9ClpBgJJEIp751UjiNxyQv5aW8 XoXWIGvl3B+/1HH9KX5KLzI4giLsno8JG3Fdi160I6hFq3VuwHoyMLB5+yTfm0rQGM ft3cFmuvUu98qVuENaC37OFNzo+YoGtgsyt8/snA9wGVP7bw5FC0oV5njpUCEPcR41 5+D4BlQmYxVhwMePy3wwbShEsC5NSlbVwlvLDYEXzJlWZaJEj99jsL1oaTMalZLHv6 Z+XB2iaAGpJhJZfSIUp9l5KUpxum23FT7/Mv5O5IyFQ76BTa7QvdA4gmcJFXhuvCEo uUBkubkcJ8KPQ== Date: Tue, 27 May 2025 18:05:00 +0000 To: Eli Zaretskii <eliz@HIDDEN> From: Pip Cet <pipcet@HIDDEN> Subject: Re: bug#78590: 31.0.50; print_object calls strout unsafely Message-ID: <87sekq6iba.fsf@HIDDEN> In-Reply-To: <86r00bxl71.fsf@HIDDEN> References: <8734cra4x7.fsf@HIDDEN> <87h6178d6w.fsf@HIDDEN> <86r00bxl71.fsf@HIDDEN> Feedback-ID: 112775352:user:proton X-Pm-Message-ID: 6ca39dc4e668e7bf18506c72a6d122adddb8bb60 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 78590 Cc: 78590 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) "Eli Zaretskii" <eliz@HIDDEN> writes: >> Date: Mon, 26 May 2025 18:00:28 +0000 >> From: Pip Cet via "Bug reports for GNU Emacs, >> the Swiss army knife of text editors" <bug-gnu-emacs@HIDDEN> >> >> Pip Cet <pipcet@HIDDEN> writes: >> >> > It's probably not worth it to come up with a complicated fix here: let= 's >> > just use SAFE_ALLOCA_STRING, and add a comment explaining the reasons >> > (GC, Lisp code modifying the string that is being printed). >> >> OK for master? > > I agree that the current code is buggy because it keeps referencing a > Lisp string's data via a 'char *' pointer while calling a Lisp > function PRINTCHARFUN. How about calling Fmapc (printcharfun, string) at that point, from print_string? That avoids making any assumptions about our string, and will be as resilient as mapc is against unreasonable self-modification of strings (bug#75845). > How about replacing iteration over a C 'char *' buffer with iteration > over the original string (using SREF or string_char_and_length)? That > is, instead of > > =09 int len, ch =3D (string_char_and_length > =09=09=09 ((const unsigned char *) ptr + i, &len)); > use > > =09 int len, ch =3D (string_char_and_length > =09=09=09 (SDATA (string) + i, &len)); > > where 'string' is the original Lisp string to print? That's what print_string does (even though it should be more careful, which is most easily achieved by delegating to Fmapc and fixing that). It does, however, also transform the string by escaping some characters, which seems incorrect to me in these circumstances (and would mean changing existing behavior). > If this requires adding an additional argument to strout, to pass the > Lisp string, which will be used only in the last 'else' clause there, > that's not difficult, right? But we already have print_string, which does almost exactly that, right? All it needs is an extra argument to avoid the byte8 escaping (unless I'm wrong and we actually want that to happen to our string here). Pip
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at 78590) by debbugs.gnu.org; 26 May 2025 18:48:28 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon May 26 14:48:28 2025 Received: from localhost ([127.0.0.1]:59700 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJcs8-0006hP-7N for submit <at> debbugs.gnu.org; Mon, 26 May 2025 14:48:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35598) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1uJcs6-0006gy-Uo for 78590 <at> debbugs.gnu.org; Mon, 26 May 2025 14:48:27 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <eliz@HIDDEN>) id 1uJcs0-0003MP-Mt; Mon, 26 May 2025 14:48:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=hNETpre0ifahOHhB90nmliFer+WRwW6UUuz3jiGfKw4=; b=NP+WXxmr6Yeh Q+FOz4DR2uRbqS8PBMspA2KdsgfMk4Vb/jzh1kbaCmq+uOtQktlpsi0H65VDz51HIIpXROp5JXYV8 7MHvoP3MEU91A+Ng/Y0jmM5I15e/VyfghEej9ES66etmfnD8d03nKj9ZNASH7B0ohLJBj2puCyb+9 QHVqQcmeFsuh3ubtKd8KCcsVx4Mc/mwIigcPJ8kkCVo7sbDxFZxPoKiISXAZhVoiMU2DlQIdDB1Kw treBSdsua6RU0WaHolYRkuXzohDA+zcxRcS8r4dVdvsDPyt3DXFVe5gxpctQCfhiZ6Osx5Bnt/nvE 7Ub4AmJtvuW92puqWNOUhQ==; Date: Mon, 26 May 2025 21:48:18 +0300 Message-Id: <86r00bxl71.fsf@HIDDEN> From: Eli Zaretskii <eliz@HIDDEN> To: Pip Cet <pipcet@HIDDEN> In-Reply-To: <87h6178d6w.fsf@HIDDEN> (bug-gnu-emacs@HIDDEN) Subject: Re: bug#78590: 31.0.50; print_object calls strout unsafely References: <8734cra4x7.fsf@HIDDEN> <87h6178d6w.fsf@HIDDEN> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 78590 Cc: 78590 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -3.3 (---) > Date: Mon, 26 May 2025 18:00:28 +0000 > From: Pip Cet via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" <bug-gnu-emacs@HIDDEN> > > Pip Cet <pipcet@HIDDEN> writes: > > > It's probably not worth it to come up with a complicated fix here: let's > > just use SAFE_ALLOCA_STRING, and add a comment explaining the reasons > > (GC, Lisp code modifying the string that is being printed). > > OK for master? I agree that the current code is buggy because it keeps referencing a Lisp string's data via a 'char *' pointer while calling a Lisp function PRINTCHARFUN. But I wonder whether the best solution is to copy the string to a C buffer. E.g., what if the string is very long? we'd just have two copies of it during the print, which increases memory pressure. How about replacing iteration over a C 'char *' buffer with iteration over the original string (using SREF or string_char_and_length)? That is, instead of int len, ch = (string_char_and_length ((const unsigned char *) ptr + i, &len)); use int len, ch = (string_char_and_length (SDATA (string) + i, &len)); where 'string' is the original Lisp string to print? If this requires adding an additional argument to strout, to pass the Lisp string, which will be used only in the last 'else' clause there, that's not difficult, right? Thanks.
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at 78590) by debbugs.gnu.org; 26 May 2025 18:00:42 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon May 26 14:00:42 2025 Received: from localhost ([127.0.0.1]:59331 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJc7u-0003Ep-EZ for submit <at> debbugs.gnu.org; Mon, 26 May 2025 14:00:42 -0400 Received: from mail-24418.protonmail.ch ([109.224.244.18]:28071) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <pipcet@HIDDEN>) id 1uJc7r-0003EB-To for 78590 <at> debbugs.gnu.org; Mon, 26 May 2025 14:00:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1748282433; x=1748541633; bh=vId5lIQwyK23S6SR3oTTDicpgKNCVHxRXVfY1D7y9Fk=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=k71vZ/w2N9FF4fSANpFwqBVW5RSUhyPnSj6Yw7rLAedMaxl1M57v6t6ONRGflijVl TQSNUIbtPerwH0rBGLw7+LawN2OGIRouh4ZtKkdtFSf53dgy1rYmWms8yWI8YJZQCw ++d/7/GZGjzraaa0Or7wkfhvPcL8SYeX/C809MaNI7h+dap6CcZddPUF9Fl6/w9tC5 L0o4tv6HFkZFMM0wlQRTJO2ag9GDjsBSEN3QOu2lanCyN1EOQFVUtp+tBkHNlhgghp mYNFry98uPNw+Zv/wIMj5hsFiEmqxs72K80Z15L7GIDWI3tRVQ/Cghtu/mcu71PqUW UTHFYzDAXQPLA== Date: Mon, 26 May 2025 18:00:28 +0000 To: 78590 <at> debbugs.gnu.org From: Pip Cet <pipcet@HIDDEN> Subject: Re: 31.0.50; print_object calls strout unsafely Message-ID: <87h6178d6w.fsf@HIDDEN> In-Reply-To: <8734cra4x7.fsf@HIDDEN> References: <8734cra4x7.fsf@HIDDEN> Feedback-ID: 112775352:user:proton X-Pm-Message-ID: 8e2c12673ea7dc4dcf6d780921802fd62b88aa6e MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 78590 X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) Pip Cet <pipcet@HIDDEN> writes: > It's probably not worth it to come up with a complicated fix here: let's > just use SAFE_ALLOCA_STRING, and add a comment explaining the reasons > (GC, Lisp code modifying the string that is being printed). OK for master? From a8f2d405f704bbff8014cf82c7c82f4d3f85fc40 Mon Sep 17 00:00:00 2001 From: Pip Cet <pipcet@HIDDEN> Subject: [PATCH] Fix unsafe SDATA usage in print.c (bug#78590) * src/print.c (print_object): Avoid unsafe SDATA usage; create a copy of the string instead. * test/src/print-tests.el (test-print-number-realloc): New test. --- src/print.c | 9 ++++++++- test/src/print-tests.el | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/print.c b/src/print.c index b17ec337f70..0c7a630702c 100644 --- a/src/print.c +++ b/src/print.c @@ -2282,7 +2282,14 @@ print_object (Lisp_Object obj, Lisp_Object printchar= fun, bool escapeflag) =09} else if (STRINGP (num)) =09{ -=09 strout (SSDATA (num), SCHARS (num), SBYTES (num), printcharfun); +=09 /* Use a local copy of the string, to guard against GC +=09 * relocation and Lisp code modifying the string being +=09 * printed. */ +=09 char *ptr; +=09 USE_SAFE_ALLOCA; +=09 SAFE_ALLOCA_STRING (ptr, num); +=09 strout (ptr, SCHARS (num), SBYTES (num), printcharfun); +=09 SAFE_FREE (); =09 goto next_obj; =09} } diff --git a/test/src/print-tests.el b/test/src/print-tests.el index af57311135b..036248fd091 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el @@ -540,5 +540,23 @@ test-print-unreadable-function-buffer (should (eq callback-buffer buffer)) (should (equal str "tata")))) =20 +(ert-deftest test-print-number-realloc () + ;; Test for bug#78590. Note that this may in rare cases crash unfixed + ;; Emacs versions. + (let ((print-circle t) + (print-number-table (make-hash-table)) + (print-continuous-numbering t) + (str "yy") + (outstr "")) + (garbage-collect) + (ignore (make-string 100 ?a)) + (puthash str (make-string 3 ?x) print-number-table) + (prin1 str + (lambda (c) + (setq outstr (concat outstr (string c))) + (garbage-collect) + (ignore (make-string 100 ?b)))) + (should (equal outstr "xxx")))) + (provide 'print-tests) ;;; print-tests.el ends here --=20 2.48.1
bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.Received: (at submit) by debbugs.gnu.org; 26 May 2025 13:16:55 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon May 26 09:16:55 2025 Received: from localhost ([127.0.0.1]:56060 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1uJXhG-0006N6-Rx for submit <at> debbugs.gnu.org; Mon, 26 May 2025 09:16:55 -0400 Received: from lists.gnu.org ([2001:470:142::17]:38276) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <pipcet@HIDDEN>) id 1uJXhD-0006M7-LV for submit <at> debbugs.gnu.org; Mon, 26 May 2025 09:16:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <pipcet@HIDDEN>) id 1uJXgk-0006wJ-32 for bug-gnu-emacs@HIDDEN; Mon, 26 May 2025 09:16:34 -0400 Received: from mail-0201.mail-europe.com ([51.77.79.158]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <pipcet@HIDDEN>) id 1uJXgh-0007o3-4S for bug-gnu-emacs@HIDDEN; Mon, 26 May 2025 09:16:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1748265371; x=1748524571; bh=ECxs2t1LsO2KRrsnsX0nNoOshPHd0iWIiwdXFJdWs8I=; h=Date:To:From:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector: List-Unsubscribe:List-Unsubscribe-Post; b=AzZdeRGJ5m5+5Mzt+1T+UYybvkn4aSdNsRiiMZXc6B3VFJLuBTGYKkrKk3THOZ8Cf Hwk8ETVqTTiHKZujj4XBWHONps9pkdTWYk5q3MzWtmPtpgzEzTwcezakJEpSzVp+gs hqwcW6yTkJeA3zr88TDqG4e5S1+6sYvsSJ2wdGp8XlmdtENM7VDLIua6sdaJqXeDJN GR3HIfO/9uTFW9pHMoW6qt9wcNE1IniZlMujFZErCI5Za/fO14A/l0TetBDBd3vuTL m4zaqkKLPUQvwRstyASI09N1zfrA3uKR+aLsYsKlleHmR38jN2H6TknUHfyr0prKlP tqfFCTklsobZw== Date: Mon, 26 May 2025 13:16:08 +0000 To: bug-gnu-emacs@HIDDEN From: Pip Cet <pipcet@HIDDEN> Subject: 31.0.50; print_object calls strout unsafely Message-ID: <8734cra4x7.fsf@HIDDEN> Feedback-ID: 112775352:user:proton X-Pm-Message-ID: 371edcce1e99b43125bc3334de0323e5e28e5565 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=51.77.79.158; envelope-from=pipcet@HIDDEN; helo=mail-0201.mail-europe.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -0.0 (/) This is a bug of the "SDATA used after potential GC" type in print.c. It requires using the print-number-table feature and a custom printcharfun. When print_object finds a string (not a fixnum or t) in the print-number-table, it calls: =09 strout (SSDATA (num), SCHARS (num), SBYTES (num), printcharfun); This assumes num (which is a string) isn't relocated in the middle of printcharfun, but printcharfun is an arbitrary Lisp function, which can trigger garbage collection and relocate the string. It's a bit hard to reproduce this bug because recursive print invocations are currently broken and crash Emacs, but this works: ;; -*- lexical-binding: t; -*- (let ((print-circle t) (print-number-table (make-hash-table)) (print-continuous-numbering t) (str "yy") (outstr "")) (garbage-collect) (make-string 100 ?a) (puthash str (make-string 3 ?x) print-number-table) (prin1 str (lambda (c) (setq outstr (concat outstr (string c))) (garbage-collect) (make-string 100 ?b))) (message "outstr %S" outstr)) The expected output is: outstr "xxx" The actual output (on this machine) is: outstr "xbb" After the first character is printed (appended to outstr), printcharfun calls garbage-collect, which relocates the string we're printing. The string's data pointer now points to unallocated space which is reused by (make-string 100 ?b) and filled with 'b' rather than 'x'. We continue to print the incorrect string. It's probably not worth it to come up with a complicated fix here: let's just use SAFE_ALLOCA_STRING, and add a comment explaining the reasons (GC, Lisp code modifying the string that is being printed). All other calls to strout look safe. The other usages of SDATA/SSDATA in print.c look okay at first glance, with this exception: static void print_unwind (Lisp_Object saved_text) { memcpy (print_buffer.buffer, SDATA (saved_text), SCHARS (saved_text)); } That should probably be SBYTES (saved_text), but recursive print invocations don't work, and this particular call won't do anything useful because print_buffer.pos and print_buffer.pos_byte aren't restored, as far as I can see.
Pip Cet <pipcet@HIDDEN>
:bug-gnu-emacs@HIDDEN
.
Full text available.bug-gnu-emacs@HIDDEN
:bug#78590
; Package emacs
.
Full text available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997 nCipher Corporation Ltd,
1994-97 Ian Jackson.