From ebb8bed911e0829371bef75b29f7ab7c1095edec Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 4 Jun 2011 16:42:31 +0000 Subject: [PATCH] fix segfault due to limit of hashtable entries (global variables) discovered by Jb_boin: unlimit to 2^30 minus epsilon --- check.t | 4 ++-- main.c | 21 +++++++++++++++------ sh.h | 7 ++++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/check.t b/check.t index ecd0ec3..c4cfe01 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.458 2011/06/04 16:11:16 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.459 2011/06/04 16:42:28 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -25,7 +25,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R40 2011/05/29 + @(#)MIRBSD KSH R40 2011/06/04 description: Check version of shell. stdin: diff --git a/main.c b/main.c index e913e80..aff30b2 100644 --- a/main.c +++ b/main.c @@ -33,7 +33,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.191 2011/05/29 16:31:42 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.192 2011/06/04 16:42:30 tg Exp $"); extern char **environ; @@ -1457,12 +1457,21 @@ texpand(struct table *tp, size_t nsize) struct tbl *tblp, **pp; struct tbl **ntblp, **otblp = tp->tbls; + i = 1; + i <<= 30; + if (nsize > i) + internal_errorf("hash table size limit reached"); + ntblp = alloc2(nsize, sizeof(struct tbl *), tp->areap); - for (i = 0; i < nsize; i++) - ntblp[i] = NULL; + memset(ntblp, 0, nsize * sizeof(struct tbl *)); tp->size = nsize; - /* table can get 80% full */ - tp->nfree = (nsize * 4) / 5; + if (nsize == i) { + /* cannot be grown any more, use a fixed value */ + tp->nfree = i - 65536; + } else /* (nsize < 2^30) */ { + /* table can get 80% full */ + tp->nfree = (nsize * 4) / 5; + } tp->tbls = ntblp; if (otblp == NULL) return; @@ -1547,7 +1556,7 @@ ktenter(struct table *tp, const char *n, uint32_t h) if ((p = ktscan(tp, n, h, &pp))) return (p); - if (tp->nfree <= 0) { + if (tp->nfree == 0) { /* too full */ texpand(tp, 2 * tp->size); goto Search; diff --git a/sh.h b/sh.h index d390dd9..7467840 100644 --- a/sh.h +++ b/sh.h @@ -151,9 +151,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.472 2011/06/04 16:11:19 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.473 2011/06/04 16:42:31 tg Exp $"); #endif -#define MKSH_VERSION "R40 2011/05/29" +#define MKSH_VERSION "R40 2011/06/04" #ifndef MKSH_INCLUDES_ONLY @@ -935,7 +935,8 @@ extern struct shf shf_iob[]; struct table { Area *areap; /* area to allocate entries */ struct tbl **tbls; /* hashed table items */ - short size, nfree; /* hash size (always 2^^n), free entries */ + uint32_t size; /* table size (always 2^n) */ + uint32_t nfree; /* free table entries */ }; struct tbl { /* table item */