This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(perl #132147) don't cache invalid pages
[perl5.git] / ext / SDBM_File / sdbm.c
index 5241fea..bdb5f47 100644 (file)
 # include <sys/file.h>
 #endif
 
-#ifdef I_STRING
-# ifndef __ultrix__
-#  include <string.h>
-# endif
-#else
-# include <strings.h>
-#endif
+#include <string.h>
 
 /*
  * externals
 extern "C" {
 #endif
 
-extern Malloc_t malloc proto((MEM_SIZE));
-extern Free_t free proto((Malloc_t));
+extern Malloc_t malloc(MEM_SIZE);
+extern Free_t free(Malloc_t);
 
 #ifdef __cplusplus
 }
 #endif
 
+const datum nullitem = {0, 0};
+
 /*
  * forward
  */
-static int getdbit proto((DBM *, long));
-static int setdbit proto((DBM *, long));
-static int getpage proto((DBM *, long));
-static datum getnext proto((DBM *));
-static int makroom proto((DBM *, long, int));
+static int getdbit(DBM *, long);
+static int setdbit(DBM *, long);
+static int getpage(DBM *, long);
+static datum getnext(DBM *);
+static int makroom(DBM *, long, int);
 
 /*
  * useful macros
@@ -402,6 +398,12 @@ sdbm_firstkey(DBM *db)
        if (lseek(db->pagf, OFF_PAG(0), SEEK_SET) < 0
            || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
                return ioerr(db), nullitem;
+        if (!chkpage(db->pagbuf)) {
+            errno = EINVAL;
+            ioerr(db);
+            db->pagbno = -1;
+            return nullitem;
+        }
        db->pagbno = 0;
        db->blkptr = 0;
        db->keyptr = 0;
@@ -450,8 +452,12 @@ getpage(DBM *db, long int hash)
                if (lseek(db->pagf, OFF_PAG(pagb), SEEK_SET) < 0
                    || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
                        return 0;
-               if (!chkpage(db->pagbuf))
-                       return 0;
+               if (!chkpage(db->pagbuf)) {
+                    errno = EINVAL;
+                    db->pagbno = -1;
+                    ioerr(db);
+                    return 0;
+                }
                db->pagbno = pagb;
 
                debug(("pag read: %d\n", pagb));
@@ -547,8 +553,12 @@ getnext(DBM *db)
                db->pagbno = db->blkptr;
                if (read(db->pagf, db->pagbuf, PBLKSIZ) <= 0)
                        break;
-               if (!chkpage(db->pagbuf))
-                       break;
+               if (!chkpage(db->pagbuf)) {
+                    errno = EINVAL;
+                    db->pagbno = -1;
+                    ioerr(db);
+                    break;
+                }
        }
 
        return ioerr(db), nullitem;