aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-06-16 18:43:46 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-06-16 18:43:46 +0300
commit52acc6d5ac3e4bf32924dc0819db19c654889436 (patch)
tree8d4eea9b82bcfdc4eeafbceed2206634ef3d4c89
parent5ea6f531857cb61946456c2582f7eaa20ceba18b (diff)
downloadgdbm-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--NEWS17
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/bucket.c4
-rw-r--r--src/falloc.c2
-rw-r--r--src/gdbmopen.c2
-rw-r--r--src/gdbmsetopt.c2
-rw-r--r--src/gdbmtool.c2
8 files changed, 21 insertions, 14 deletions
diff --git a/NEWS b/NEWS
index ba245aa..76f7db0 100644
--- a/NEWS
+++ b/NEWS
@@ -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;

Return to:

Send suggestions and report system problems to the System administrator.