diff options
-rw-r--r-- | src/falloc.c | 13 | ||||
-rw-r--r-- | src/gdbm.h.in | 3 | ||||
-rw-r--r-- | src/gdbmdefs.h | 7 | ||||
-rw-r--r-- | src/gdbmerrno.c | 3 | ||||
-rw-r--r-- | src/gdbmopen.c | 4 | ||||
-rw-r--r-- | src/gdbmtool.c | 37 |
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 */ | ||
55 | static int inline | ||
56 | gdbm_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 | ||
241 | static void | ||
242 | av_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 | |||
238 | void | 253 | void |
@@ -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; |