diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2008-05-11 22:21:26 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2008-05-11 22:21:26 +0000 |
commit | 7eb9b2c9806f4234440c285967032043f8ddcb06 (patch) | |
tree | 154ff246966c3939266fcd33541244d4bd677f1f /lib/libc | |
parent | c08e12cb4bc1fb7c6dd0eb0017f1ed139d2fc4dd (diff) |
Fix a crash when iterating over a hash and removing its elements.
From Patrick Keshishian. OK pvalchev@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/db/hash/hash.c | 23 | ||||
-rw-r--r-- | lib/libc/db/hash/hash_page.c | 10 |
2 files changed, 22 insertions, 11 deletions
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c index adc13c708ed..1ec9ec8bf00 100644 --- a/lib/libc/db/hash/hash.c +++ b/lib/libc/db/hash/hash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hash.c,v 1.21 2006/03/19 19:51:53 otto Exp $ */ +/* $OpenBSD: hash.c,v 1.22 2008/05/11 22:21:25 millert Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -705,7 +705,7 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) hashp->cndx = 1; hashp->cpage = NULL; } - + next_bucket: for (bp = NULL; !bp || !bp[0]; ) { if (!(bufp = hashp->cpage)) { for (bucket = hashp->cbucket; @@ -724,8 +724,18 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) hashp->cbucket = -1; return (ABNORMAL); } - } else + } else { bp = (u_int16_t *)hashp->cpage->page; + if (flag == R_NEXT) { + hashp->cndx += 2; + if (hashp->cndx > bp[0]) { + hashp->cpage = NULL; + hashp->cbucket++; + hashp->cndx = 1; + goto next_bucket; + } + } + } #ifdef DEBUG assert(bp); @@ -755,13 +765,6 @@ hash_seq(const DB *dbp, DBT *key, DBT *data, u_int32_t flag) key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; data->data = (u_char *)hashp->cpage->page + bp[ndx + 1]; data->size = bp[ndx] - bp[ndx + 1]; - ndx += 2; - if (ndx > bp[0]) { - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else - hashp->cndx = ndx; } return (SUCCESS); } diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c index a744e689b41..05bc2734506 100644 --- a/lib/libc/db/hash/hash_page.c +++ b/lib/libc/db/hash/hash_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hash_page.c,v 1.18 2007/09/17 07:07:23 moritz Exp $ */ +/* $OpenBSD: hash_page.c,v 1.19 2008/05/11 22:21:25 millert Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -149,6 +149,14 @@ __delpair(HTAB *hashp, BUFHEAD *bufp, int ndx) bp[i - 1] = bp[i + 1] + pairlen; } } + if (ndx == hashp->cndx) { + /* + * We just removed pair we were "pointing" to. + * By moving back the cndx we ensure subsequent + * hash_seq() calls won't skip over any entries. + */ + hashp->cndx -= 2; + } } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen; |