aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2019-07-21 11:20:07 -0700
committerPaul Eggert2019-07-21 11:24:11 -0700
commitc72e6328b408805953a5adf832b5c5cc9f3a75e7 (patch)
tree33e715f4a28ff12e9d6d5fa1b8cdc81d406a5838
parentcf285946bee56912286f75e4d1215214bc7c5b4b (diff)
downloademacs-c72e6328b408805953a5adf832b5c5cc9f3a75e7.tar.gz
emacs-c72e6328b408805953a5adf832b5c5cc9f3a75e7.zip
Avoid integer overflow in hash table size
* src/fns.c (INDEX_SIZE_BOUND): Use a tighter bound. (maybe_resize_hash_table): Avoid integer overflow when checking for hash table size overflow. Fix confusion between INDEX_SIZE_BOUND (which is for the index vector) and hash table size. Fix typo in debugging message when ENABLE_CHECKING.
-rw-r--r--src/fns.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/fns.c b/src/fns.c
index 819eaec7c74..8eefa7c72b2 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4042,9 +4042,14 @@ allocate_hash_table (void)
4042} 4042}
4043 4043
4044/* An upper bound on the size of a hash table index. It must fit in 4044/* An upper bound on the size of a hash table index. It must fit in
4045 ptrdiff_t and be a valid Emacs fixnum. */ 4045 ptrdiff_t and be a valid Emacs fixnum. This is an upper bound on
4046 VECTOR_ELTS_MAX (see alloc.c) and gets as close as we can without
4047 violating modularity. */
4046#define INDEX_SIZE_BOUND \ 4048#define INDEX_SIZE_BOUND \
4047 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX / word_size)) 4049 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, \
4050 ((min (PTRDIFF_MAX, SIZE_MAX) \
4051 - header_size - GCALIGNMENT) \
4052 / word_size)))
4048 4053
4049/* Create and initialize a new hash table. 4054/* Create and initialize a new hash table.
4050 4055
@@ -4169,11 +4174,13 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4169 else 4174 else
4170 { 4175 {
4171 double float_new_size = old_size * (rehash_size + 1); 4176 double float_new_size = old_size * (rehash_size + 1);
4172 if (float_new_size < INDEX_SIZE_BOUND + 1) 4177 if (float_new_size < EMACS_INT_MAX)
4173 new_size = float_new_size; 4178 new_size = float_new_size;
4174 else 4179 else
4175 new_size = INDEX_SIZE_BOUND + 1; 4180 new_size = EMACS_INT_MAX;
4176 } 4181 }
4182 if (PTRDIFF_MAX < new_size)
4183 new_size = PTRDIFF_MAX;
4177 if (new_size <= old_size) 4184 if (new_size <= old_size)
4178 new_size = old_size + 1; 4185 new_size = old_size + 1;
4179 4186
@@ -4181,7 +4188,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4181 avoid problems if memory is exhausted. larger_vecalloc 4188 avoid problems if memory is exhausted. larger_vecalloc
4182 finishes computing the size of the replacement vectors. */ 4189 finishes computing the size of the replacement vectors. */
4183 Lisp_Object next = larger_vecalloc (h->next, new_size - old_size, 4190 Lisp_Object next = larger_vecalloc (h->next, new_size - old_size,
4184 INDEX_SIZE_BOUND / 2); 4191 PTRDIFF_MAX / 2);
4185 ptrdiff_t next_size = ASIZE (next); 4192 ptrdiff_t next_size = ASIZE (next);
4186 for (ptrdiff_t i = old_size; i < next_size - 1; i++) 4193 for (ptrdiff_t i = old_size; i < next_size - 1; i++)
4187 gc_aset (next, i, make_fixnum (i + 1)); 4194 gc_aset (next, i, make_fixnum (i + 1));
@@ -4216,7 +4223,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4216 4223
4217#ifdef ENABLE_CHECKING 4224#ifdef ENABLE_CHECKING
4218 if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h) 4225 if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h)
4219 message ("Growing hash table to: %"pD"d", new_size); 4226 message ("Growing hash table to: %"pD"d", next_size);
4220#endif 4227#endif
4221 } 4228 }
4222} 4229}