bug#60928: [PATCH] bugfix/make_hash_table: fix segfault when arg< 0 for make-hash-table

Blake Shaw via "Bug reports for GUILE, GNU's Ubiquitous Extension Language" <[email protected]>
Newsgroups gmane.lisp.guile.bugs
Message-ID <[email protected]>
* libguile/hashtab.c (make_hash_table): FIX SEGMENTATION FAULT
Currently on Guix if a user evokes (make-hash-table arg) where
arg < 0, guile segfaults.

This patch adds the most straight forward solution, checking
if the value passed to make-hash-table is less than 0, and if so,
throwing an error with scm_out_of_range to avoid segfaulting.

It builds and passes all tests in a guix shell using the
command:

$ guix shell automake autoconf make flex gnulib gettext libtool \
gperf gmp git libffi -D guile guix -C -- \
./autogen.sh && ./configure && make && make check

afterwards, using: ./meta/guile -q
=> scheme@(guile-user)> (make-hash-table -1)
   ice-9/boot-9.scm:1685:16: In procedure raise-exception:
   Value out of range 0 to< 18446744073709551615: -1

as desired...

I'm not familiar with the inner workings of libguile, but
figured I'd offer a fix regardless, so take this this patch
with a grain of salt, it was a quicky...
---
 libguile/hashtab.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/libguile/hashtab.c b/libguile/hashtab.c
index b4f004c1d..9cb5d7a47 100644
--- a/libguile/hashtab.c
+++ b/libguile/hashtab.c
@@ -84,23 +84,24 @@ make_hash_table (unsigned long k, const char *func_name)
   SCM vector;
   scm_t_hashtable *t;
   int i = 0, n = k ? k : 31;
-  while (i + 1 < HASHTABLE_SIZE_N && n > hashtable_size[i])
-    ++i;
-  n = hashtable_size[i];
-
-  vector = scm_c_make_vector (n, SCM_EOL);
-
-  t = scm_gc_malloc_pointerless (sizeof (*t), s_hashtable);
-  t->min_size_index = t->size_index = i;
-  t->n_items = 0;
-  t->lower = 0;
-  t->upper = 9 * n / 10;
+   if (k < i) {
+     scm_out_of_range (func_name, scm_from_ulong (k));
+  } else {
+     while (i + 1 < HASHTABLE_SIZE_N && n > hashtable_size[i])
+       ++i;
+     n = hashtable_size[i];
+     vector = scm_c_make_vector (n, SCM_EOL);
+     t = scm_gc_malloc_pointerless (sizeof (*t), s_hashtable);
+     t->min_size_index = t->size_index = i;
+     t->n_items = 0;
+     t->lower = 0;
+     t->upper = 9 * n / 10;
 
   /* FIXME: we just need two words of storage, not three */
-  return scm_double_cell (scm_tc7_hashtable, SCM_UNPACK (vector),
-                          (scm_t_bits)t, 0);
+     return scm_double_cell (scm_tc7_hashtable, SCM_UNPACK (vector),
+                             (scm_t_bits)t, 0);
+   }
 }
-
 void
 scm_i_rehash (SCM table,
 	      scm_t_hash_fn hash_fn,
-- 
2.38.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.