>From 3480071dfab30eaca7f1d014600b864d2ea22f62 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 15 Feb 2020 15:12:34 -0800 Subject: [PATCH] Fix C-h C-h bug due to mutating a hash key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem reported by Federico Tedin (Bug#39529). The problem was that dumping uses a hash table based on 'equal' when purecopying compiled objects, but then modifies the compiled objects while they are keys in the table. This no-no was uncovered by the sxhash fixes in 2020-01-07T19:23:11Z!eggert@cs.ucla.edu. Eli Zaretski pinpointed the patch that triggered the bug. * src/lread.c (read1): When reading a compiled object, replace its docstring with a unique negative integer instead of with 0, so that purecopy doesn’t unify it with some other compiled object that happens to have the same Lisp code. --- src/lread.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lread.c b/src/lread.c index c124d5a1d8..f39e81ae2c 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2974,6 +2974,21 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) vec = XVECTOR (tmp); if (vec->header.size == 0) invalid_syntax ("Empty byte-code object"); + + if (COMPILED_DOC_STRING < vec->header.size + && AREF (tmp, COMPILED_DOC_STRING) == make_fixnum (0)) + { + /* read_list found a docstring like '(#$ . 5521)' and treated it + as 0. This placeholder 0 would lead to accidental sharing in + purecopy's hash-consing, so replace it with a (hopefully) + unique integer placeholder, which is negative so that it is + not confused with a DOC file offset. Eventually + Snarf-documentation should replace the placeholder with the + actual docstring. */ + EMACS_UINT hash = XHASH (tmp) | (INTMASK - INTMASK / 2); + ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash)); + } + make_byte_code (vec); return tmp; } -- 2.17.1