diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-06-16 18:43:46 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-06-16 18:43:46 +0300 |
commit | 52acc6d5ac3e4bf32924dc0819db19c654889436 (patch) | |
tree | 8d4eea9b82bcfdc4eeafbceed2206634ef3d4c89 | |
parent | 5ea6f531857cb61946456c2582f7eaa20ceba18b (diff) | |
download | gdbm-1.15.tar.gz gdbm-1.15.tar.bz2 |
Version 1.5v1.15
* configure.ac: Version 1.5
* NEWS: Update.
* src/Makefile.am (VI_CURRENT): Increment to 6
* src/bucket.c (_gdbm_get_bucket): Fix the upper limit for
bucket_bits.
* src/falloc.c (push_avail_block): Fill the allocated block
with 0s.
-rw-r--r-- | NEWS | 17 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/bucket.c | 4 | ||||
-rw-r--r-- | src/falloc.c | 2 | ||||
-rw-r--r-- | src/gdbmopen.c | 2 | ||||
-rw-r--r-- | src/gdbmsetopt.c | 2 | ||||
-rw-r--r-- | src/gdbmtool.c | 2 |
8 files changed, 21 insertions, 14 deletions
@@ -1,48 +1,55 @@ -GNU dbm NEWS -- history of user-visible changes. 2018-05-25 +GNU dbm NEWS -- history of user-visible changes. 2018-06-16 Copyright (C) 1990-2018 Free Software Foundation, Inc. See the end of file for copying conditions. Please send gdbm bug reports to <bug-gdbm@gnu.org>. -Version 1.14.90 +Version 1.15 - 2018-06-15 -FIXME: BUMP VI_MAJOR +* Extensive database consistency checking -* Implement database consistency checks +GDBM tries to detect inconsistencies in input database files as +early as possible. When an inconcistency is detected, a helpful +diagnostics is returned and the database is marked as needing +recovery. From this moment on, any GDBM function trying to access +the database will immediately return error code (instead of +eventually segfaulting as previous versions did). In order to +reconstruct the database and return it to healthy state, the +gdbm_recover function should be used. Special thanks to Lionel Debroux and Craig Young for investing their time and efforts in testing and providing valuable feedback. * Improved error checking * Removed gdbm-1.8.3 compatibility layer * Commands can be given to gdbmtool in the command line The syntax is: gdbmtool DBNAME COMMAND [ARGS...] Multiple commands are separated by semicolon (take care to escape it), e.g.: gdbmtool t.db count\; avail * Fixed data conversion bugs in storing structured keys or content * New member in the gdbm_recovery structure: duplicate_keys. Upon return from gdbm_recover, this member holds the number of keys -that were not recovered, because the same key has already been stored +that has not been recovered, because the same key had already been stored in the database. The actual number of stored keys is thus recovered_keys - duplicate_keys. * New error codes. GDBM_BAD_BUCKET "Malformed bucket header" GDBM_BAD_HEADER "Malformed database file header" GDBM_BAD_AVAIL "Malformed avail_block" GDBM_BAD_HASH_TABLE "Malformed hash table" GDBM_BAD_DIR_ENTRY "Invalid directory entry" diff --git a/configure.ac b/configure.ac index 48ad675..505ba09 100644 --- a/configure.ac +++ b/configure.ac @@ -7,26 +7,26 @@ # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GDBM is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ m4_define([_GDBM_VERSION_MAJOR], 1) -m4_define([_GDBM_VERSION_MINOR], 14) -m4_define([_GDBM_VERSION_PATCH], 90) +m4_define([_GDBM_VERSION_MINOR], 15) +dnl m4_define([_GDBM_VERSION_PATCH], 0) AC_INIT([gdbm], _GDBM_VERSION_MAJOR._GDBM_VERSION_MINOR[]m4_ifdef([_GDBM_VERSION_PATCH],._GDBM_VERSION_PATCH), [bug-gdbm@gnu.org],, [http://www.gnu.org/software/gdbm]) AC_PREREQ(2.69) AC_CONFIG_SRCDIR([src/gdbmdefs.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([autoconf.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([gnits 1.11 std-options silent-rules]) diff --git a/src/Makefile.am b/src/Makefile.am index 0d2ca53..2710bf0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,25 +24,25 @@ noinst_HEADERS = \ gdbmdefs.h\ gettext.h\ gram.h\ proto.h\ systems.h EXTRA_DIST = gdbm.h.in gdbm.magic BUILT_SOURCES = gdbm.h gram.h gram.h: gram.c # The libraries -VI_CURRENT = 5 +VI_CURRENT = 6 VI_REVISION = 0 VI_AGE = 0 lib_LTLIBRARIES = libgdbm.la libgdbm_la_LIBADD = @LTLIBINTL@ libgdbm_la_SOURCES = \ gdbmclose.c\ gdbmcount.c\ gdbmdelete.c\ gdbmdump.c\ gdbmerrno.c\ diff --git a/src/bucket.c b/src/bucket.c index a3e8f4e..4b69bbe 100644 --- a/src/bucket.c +++ b/src/bucket.c @@ -20,25 +20,25 @@ #include "autoconf.h" #include "gdbmdefs.h" #include <limits.h> #define GDBM_MAX_DIR_SIZE INT_MAX #define GDBM_MAX_DIR_HALF (GDBM_MAX_DIR_SIZE / 2) /* Initializing a new hash buckets sets all bucket entries to -1 hash value. */ void _gdbm_new_bucket (GDBM_FILE dbf, hash_bucket *bucket, int bits) { int index; - + /* Initialize the avail block. */ bucket->av_count = 0; /* Set the information fields first. */ bucket->bucket_bits = bits; bucket->count = 0; /* Initialize all bucket elements. */ for (index = 0; index < dbf->header->bucket_elems; index++) bucket->h_table[index].hash_value = -1; } @@ -137,25 +137,25 @@ _gdbm_get_bucket (GDBM_FILE dbf, int dir_index) GDBM_DEBUG (GDBM_DEBUG_ERR, "%s: error reading bucket: %s", dbf->name, gdbm_db_strerror (dbf)); dbf->need_recovery = TRUE; _gdbm_fatal (dbf, gdbm_db_strerror (dbf)); return -1; } /* Validate the bucket */ bucket = dbf->bucket_cache[lru].ca_bucket; if (!(bucket->count >= 0 && bucket->count <= dbf->header->bucket_elems && bucket->bucket_bits >= 0 - && bucket->bucket_bits <= GDBM_HASH_BITS)) + && bucket->bucket_bits <= dbf->header->dir_bits)) { GDBM_SET_ERRNO (dbf, GDBM_BAD_BUCKET, TRUE); return -1; } /* Validate bucket_avail table */ if (gdbm_bucket_avail_table_validate (dbf, bucket)) return -1; /* Finally, store it in cache */ dbf->last_read = lru; dbf->bucket_cache[lru].ca_adr = bucket_adr; dbf->bucket = dbf->bucket_cache[lru].ca_bucket; diff --git a/src/falloc.c b/src/falloc.c index 2f21ebe..6571d9b 100644 --- a/src/falloc.c +++ b/src/falloc.c @@ -283,25 +283,25 @@ push_avail_block (GDBM_FILE dbf) /* Caclulate the size of the split block. */ av_size = ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1) + sizeof (avail_block); /* Get address in file for new av_size bytes. */ new_loc = get_elem (av_size, dbf->header->avail.av_table, &dbf->header->avail.count); if (new_loc.av_size == 0) new_loc = get_block (av_size, dbf); av_adr = new_loc.av_adr; /* Split the header block. */ - temp = malloc (av_size); + temp = calloc (1, av_size); if (temp == NULL) { GDBM_SET_ERRNO (dbf, GDBM_MALLOC_ERROR, TRUE); _gdbm_fatal (dbf, _("malloc error")); return -1; } /* Set the size to be correct AFTER the pop_avail_block. */ temp->size = dbf->header->avail.size; temp->count = 0; temp->next_block = dbf->header->avail.next_block; dbf->header->avail.next_block = av_adr; diff --git a/src/gdbmopen.c b/src/gdbmopen.c index 03cc4f4..677f1cf 100644 --- a/src/gdbmopen.c +++ b/src/gdbmopen.c @@ -145,25 +145,25 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st) && hdr->dir < st->st_size && hdr->dir_size > 0 && hdr->dir + hdr->dir_size < st->st_size)) return GDBM_BAD_HEADER; compute_directory_size (hdr->block_size, &dir_size, &dir_bits); if (!(hdr->dir_size >= dir_size)) return GDBM_BAD_HEADER; compute_directory_size (hdr->dir_size, &dir_size, &dir_bits); if (hdr->dir_bits != dir_bits) return GDBM_BAD_HEADER; - if (!(hdr->bucket_size > 0 && hdr->bucket_size > sizeof(hash_bucket))) + if (!(hdr->bucket_size > sizeof(hash_bucket))) return GDBM_BAD_HEADER; if (hdr->bucket_elems != bucket_element_count (hdr->bucket_size)) return GDBM_BAD_HEADER; if (((hdr->block_size - sizeof (gdbm_file_header)) / sizeof(avail_elem) + 1) != hdr->avail.size) return GDBM_BAD_HEADER; return 0; } diff --git a/src/gdbmsetopt.c b/src/gdbmsetopt.c index f9face0..865f5a5 100644 --- a/src/gdbmsetopt.c +++ b/src/gdbmsetopt.c @@ -45,31 +45,31 @@ get_size (void *optval, int optlen, size_t *ret) else if (optlen == sizeof (size_t)) *ret = *(size_t*) optval; else return -1; return 0; } static int setopt_gdbm_setcachesize (GDBM_FILE dbf, void *optval, int optlen) { size_t sz; - /* Optval will point to the new size of the cache. */ if (dbf->bucket_cache != NULL) { GDBM_SET_ERRNO (dbf, GDBM_OPT_ALREADY_SET, FALSE); return -1; } + /* Optval will point to the new size of the cache. */ if (get_size (optval, optlen, &sz)) { GDBM_SET_ERRNO (dbf, GDBM_OPT_ILLEGAL, FALSE); return -1; } return _gdbm_init_cache (dbf, (sz > 9) ? sz : 10); } static int setopt_gdbm_getcachesize (GDBM_FILE dbf, void *optval, int optlen) { if (!optval || optlen != sizeof (size_t)) diff --git a/src/gdbmtool.c b/src/gdbmtool.c index 6d56578..d0b2694 100644 --- a/src/gdbmtool.c +++ b/src/gdbmtool.c @@ -910,25 +910,25 @@ list_handler (struct handler_param *param) { datum key; datum data; key = gdbm_firstkey (gdbm_file); while (key.dptr) { datum nextkey = gdbm_nextkey (gdbm_file, key); data = gdbm_fetch (gdbm_file, key); if (!data.dptr) { - terror (_("cannot fetch data; the key was:")); + terror (_("%s; the key was:"), gdbm_db_strerror (gdbm_file)); datum_format (stderr, &key, dsdef[DS_KEY]); } else { datum_format (param->fp, &key, dsdef[DS_KEY]); fputc (' ', param->fp); datum_format (param->fp, &data, dsdef[DS_CONTENT]); fputc ('\n', param->fp); free (data.dptr); } free (key.dptr); key = nextkey; |