diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-03-15 20:11:22 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-03-16 09:29:09 +0200 |
commit | 40a464d322c720c88a50c3eb0a8c1d87e6079f89 (patch) | |
tree | 84c92c0ddcff3ef4f7539b4e478f037bf5070c7c | |
parent | 4046a0af3b383155b8b6d96ea6ed3ed1aa6f5079 (diff) | |
download | gdbm-40a464d322c720c88a50c3eb0a8c1d87e6079f89.tar.gz gdbm-40a464d322c720c88a50c3eb0a8c1d87e6079f89.tar.bz2 |
Don't leave erroneous bucket in GDBM_FILE if _gdbm_get_bucket fails
This fixes most of bug #501 (http://puszcza.gnu.org.ua/bugs/?501).
* src/bucket.c (_gdbm_get_bucket): Reinitialize dbf->bucket to
NULL before returning failure.
-rw-r--r-- | src/bucket.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/bucket.c b/src/bucket.c index 6b93d02..b0771aa 100644 --- a/src/bucket.c +++ b/src/bucket.c @@ -116,7 +116,7 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) { GDBM_SET_ERRNO (dbf, GDBM_FILE_SEEK_ERROR, TRUE); _gdbm_fatal (dbf, _("lseek error")); - return -1; + goto err; } /* Flush and drop the last recently used cache entry */ @@ -124,7 +124,7 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) if (dbf->bucket_cache[lru].ca_changed) { if (_gdbm_write_bucket (dbf, &dbf->bucket_cache[lru])) - return -1; + goto err; } _gdbm_cache_entry_invalidate (dbf, lru); @@ -138,7 +138,7 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) dbf->name, gdbm_db_strerror (dbf)); dbf->need_recovery = TRUE; _gdbm_fatal (dbf, gdbm_db_strerror (dbf)); - return -1; + goto err; } /* Validate the bucket */ bucket = dbf->bucket_cache[lru].ca_bucket; @@ -148,11 +148,11 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) && bucket->bucket_bits <= dbf->header->dir_bits)) { GDBM_SET_ERRNO (dbf, GDBM_BAD_BUCKET, TRUE); - return -1; + goto err; } /* Validate bucket_avail table */ if (gdbm_bucket_avail_table_validate (dbf, bucket)) - return -1; + goto err; /* Finally, store it in cache */ dbf->last_read = lru; @@ -163,6 +163,9 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) dbf->cache_entry->ca_changed = FALSE; } return 0; + err: + dbf->bucket = NULL; + return -1; } int |