aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/falloc.c13
-rw-r--r--src/gdbm.h.in3
-rw-r--r--src/gdbmdefs.h7
-rw-r--r--src/gdbmerrno.c3
-rw-r--r--src/gdbmopen.c4
-rw-r--r--src/gdbmtool.c37
6 files changed, 48 insertions, 19 deletions
diff --git a/src/falloc.c b/src/falloc.c
index 3f437a6..33a238a 100644
--- a/src/falloc.c
+++ b/src/falloc.c
@@ -154,3 +154,3 @@ _gdbm_free (GDBM_FILE dbf, off_t file_adr, int num_bytes)
154/* Gets the avail block at the top of the stack and loads it into the 154/* Gets the avail block at the top of the stack and loads it into the
155 active avail block. It does a "free" for itself! This can (and is) 155 active avail block. It does a "free" for itself! This can be (and is)
156 now called even when the avail block is not empty, so we must be 156 now called even when the avail block is not empty, so we must be
@@ -208,2 +208,9 @@ pop_avail_block (GDBM_FILE dbf)
208 208
209 if (!gdbm_avail_block_valid_p (new_blk))
210 {
211 gdbm_set_errno (dbf, GDBM_BAD_AVAIL, TRUE);
212 _gdbm_fatal (dbf, gdbm_db_strerror (dbf));
213 return -1;
214 }
215
209 /* Add the elements from the new block to the header. */ 216 /* Add the elements from the new block to the header. */
@@ -212,4 +219,4 @@ pop_avail_block (GDBM_FILE dbf)
212 { 219 {
213 while(index < new_blk->count 220 while (index < new_blk->count
214 && dbf->header->avail.count < dbf->header->avail.size) 221 && dbf->header->avail.count < dbf->header->avail.size)
215 { 222 {
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index 3d19de7..61d5707 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -223,5 +223,6 @@ extern int gdbm_copy_meta (GDBM_FILE dst, GDBM_FILE src);
223# define GDBM_BAD_HEADER 33 223# define GDBM_BAD_HEADER 33
224# define GDBM_BAD_AVAIL 34
224 225
225# define _GDBM_MIN_ERRNO 0 226# define _GDBM_MIN_ERRNO 0
226# define _GDBM_MAX_ERRNO GDBM_BAD_HEADER 227# define _GDBM_MAX_ERRNO GDBM_BAD_AVAIL
227 228
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index bd104e2..5305b0d 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -53,2 +53,9 @@ typedef struct
53 53
54/* Return true if avail_block is valid */
55static int inline
56gdbm_avail_block_valid_p (avail_block const *av)
57{
58 return (av->size >= 0 && av->count >= 0 && av->count <= av->size);
59}
60
54/* The dbm file header keeps track of the current location of the hash 61/* The dbm file header keeps track of the current location of the hash
diff --git a/src/gdbmerrno.c b/src/gdbmerrno.c
index 7124b3a..896bf70 100644
--- a/src/gdbmerrno.c
+++ b/src/gdbmerrno.c
@@ -135,3 +135,4 @@ const char * const gdbm_errlist[_GDBM_MAX_ERRNO+1] = {
135 [GDBM_BAD_BUCKET] = N_("Malformed bucket header"), 135 [GDBM_BAD_BUCKET] = N_("Malformed bucket header"),
136 [GDBM_BAD_HEADER] = N_("Malformed database file header") 136 [GDBM_BAD_HEADER] = N_("Malformed database file header"),
137 [GDBM_BAD_AVAIL] = N_("Malforemd avail_block")
137}; 138};
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 5d59f65..b84ad63 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -110,2 +110,6 @@ validate_header (gdbm_file_header const *hdr, struct stat const *st)
110 return GDBM_BAD_HEADER; 110 return GDBM_BAD_HEADER;
111
112 /* Validate the avail block */
113 if (!gdbm_avail_block_valid_p (&hdr->avail))
114 return GDBM_BAD_HEADER;
111 115
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index c522ad0..18d0e10 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -227,5 +227,8 @@ _gdbm_avail_list_size (GDBM_FILE dbf, size_t min_size)
227 227
228 lines += av_stk->count; 228 if (gdbm_avail_block_valid_p (av_stk))
229 if (lines > min_size) 229 {
230 break; 230 lines += av_stk->count;
231 if (lines > min_size)
232 break;
233 }
231 temp = av_stk->next_block; 234 temp = av_stk->next_block;
@@ -237,2 +240,14 @@ _gdbm_avail_list_size (GDBM_FILE dbf, size_t min_size)
237 240
241static void
242av_table_display (avail_elem *av_table, int count, FILE *fp)
243{
244 int i;
245
246 for (i = 0; i < count; i++)
247 {
248 fprintf (fp, " %15d %10lu \n",
249 av_table[i].av_size, (unsigned long) av_table[i].av_adr);
250 }
251}
252
238void 253void
@@ -248,8 +263,3 @@ _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf)
248 dbf->header->avail.size, dbf->header->avail.count); 263 dbf->header->avail.size, dbf->header->avail.count);
249 for (temp = 0; temp < dbf->header->avail.count; temp++) 264 av_table_display (dbf->header->avail.av_table, dbf->header->avail.count, fp);
250 {
251 fprintf (fp, " %15d %10lu \n",
252 dbf->header->avail.av_table[temp].av_size,
253 (unsigned long) dbf->header->avail.av_table[temp].av_adr);
254 }
255 265
@@ -282,7 +292,6 @@ _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf)
282 av_stk->size, av_stk->count); 292 av_stk->size, av_stk->count);
283 for (temp = 0; temp < av_stk->count; temp++) 293 if (gdbm_avail_block_valid_p (av_stk))
284 { 294 av_table_display (av_stk->av_table, av_stk->count, fp);
285 fprintf (fp, " %15d %10lu \n", av_stk->av_table[temp].av_size, 295 else
286 (unsigned long) av_stk->av_table[temp].av_adr); 296 terror (_("invalid avail_block"));
287 }
288 temp = av_stk->next_block; 297 temp = av_stk->next_block;

Return to:

Send suggestions and report system problems to the System administrator.