emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master c72e632 3/4: Avoid integer overflow in hash table s


From: Paul Eggert
Subject: [Emacs-diffs] master c72e632 3/4: Avoid integer overflow in hash table size
Date: Sun, 21 Jul 2019 14:24:20 -0400 (EDT)

branch: master
commit c72e6328b408805953a5adf832b5c5cc9f3a75e7
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/fns.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index 819eaec..8eefa7c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4042,9 +4042,14 @@ allocate_hash_table (void)
 }
 
 /* An upper bound on the size of a hash table index.  It must fit in
-   ptrdiff_t and be a valid Emacs fixnum.  */
+   ptrdiff_t and be a valid Emacs fixnum.  This is an upper bound on
+   VECTOR_ELTS_MAX (see alloc.c) and gets as close as we can without
+   violating modularity.  */
 #define INDEX_SIZE_BOUND \
-  ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX / word_size))
+  ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, \
+                   ((min (PTRDIFF_MAX, SIZE_MAX) \
+                     - header_size - GCALIGNMENT) \
+                    / word_size)))
 
 /* Create and initialize a new hash table.
 
@@ -4169,11 +4174,13 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
       else
        {
          double float_new_size = old_size * (rehash_size + 1);
-         if (float_new_size < INDEX_SIZE_BOUND + 1)
+         if (float_new_size < EMACS_INT_MAX)
            new_size = float_new_size;
          else
-           new_size = INDEX_SIZE_BOUND + 1;
+           new_size = EMACS_INT_MAX;
        }
+      if (PTRDIFF_MAX < new_size)
+       new_size = PTRDIFF_MAX;
       if (new_size <= old_size)
        new_size = old_size + 1;
 
@@ -4181,7 +4188,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
         avoid problems if memory is exhausted.  larger_vecalloc
         finishes computing the size of the replacement vectors.  */
       Lisp_Object next = larger_vecalloc (h->next, new_size - old_size,
-                                         INDEX_SIZE_BOUND / 2);
+                                         PTRDIFF_MAX / 2);
       ptrdiff_t next_size = ASIZE (next);
       for (ptrdiff_t i = old_size; i < next_size - 1; i++)
        gc_aset (next, i, make_fixnum (i + 1));
@@ -4216,7 +4223,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
 
 #ifdef ENABLE_CHECKING
       if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h)
-       message ("Growing hash table to: %"pD"d", new_size);
+       message ("Growing hash table to: %"pD"d", next_size);
 #endif
     }
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]