aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2020-02-15 15:12:34 -0800
committerPaul Eggert2020-02-15 15:18:28 -0800
commit3480071dfab30eaca7f1d014600b864d2ea22f62 (patch)
tree9cf1ad2975d575710c2bb5c84a6a28681b3e398a
parentccb15ada750ed1a2ed67bc58458022b9d96a9d44 (diff)
downloademacs-3480071dfab30eaca7f1d014600b864d2ea22f62.tar.gz
emacs-3480071dfab30eaca7f1d014600b864d2ea22f62.zip
Fix C-h C-h bug due to mutating a hash key
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.
-rw-r--r--src/lread.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/lread.c b/src/lread.c
index c124d5a1d8f..f39e81ae2cf 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2974,6 +2974,21 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2974 vec = XVECTOR (tmp); 2974 vec = XVECTOR (tmp);
2975 if (vec->header.size == 0) 2975 if (vec->header.size == 0)
2976 invalid_syntax ("Empty byte-code object"); 2976 invalid_syntax ("Empty byte-code object");
2977
2978 if (COMPILED_DOC_STRING < vec->header.size
2979 && AREF (tmp, COMPILED_DOC_STRING) == make_fixnum (0))
2980 {
2981 /* read_list found a docstring like '(#$ . 5521)' and treated it
2982 as 0. This placeholder 0 would lead to accidental sharing in
2983 purecopy's hash-consing, so replace it with a (hopefully)
2984 unique integer placeholder, which is negative so that it is
2985 not confused with a DOC file offset. Eventually
2986 Snarf-documentation should replace the placeholder with the
2987 actual docstring. */
2988 EMACS_UINT hash = XHASH (tmp) | (INTMASK - INTMASK / 2);
2989 ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash));
2990 }
2991
2977 make_byte_code (vec); 2992 make_byte_code (vec);
2978 return tmp; 2993 return tmp;
2979 } 2994 }