]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
ITS#7992 Fix memleak in prev change
[openldap] / libraries / liblmdb / mdb.c
index 895ab952b604347b0c12333d1fd8fd892cc1626b..ea9e4729025f4934af2a0e473d268f8b9973385d 100644 (file)
@@ -5,7 +5,7 @@
  *     BerkeleyDB API, but much simplified.
  */
 /*
- * Copyright 2011-2015 Howard Chu, Symas Corp.
+ * Copyright 2011-2016 Howard Chu, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1075,7 +1075,7 @@ typedef struct MDB_db {
        pgno_t          md_branch_pages;        /**< number of internal pages */
        pgno_t          md_leaf_pages;          /**< number of leaf pages */
        pgno_t          md_overflow_pages;      /**< number of overflow pages */
-       pgno_t          md_entries;             /**< number of data items */
+       mdb_size_t      md_entries;             /**< number of data items */
        pgno_t          md_root;                /**< the root page of this tree */
 } MDB_db;
 
@@ -2428,7 +2428,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
                        rc = MDB_MAP_FULL;
                        goto fail;
        }
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(MDB_VL32)
        if (!(env->me_flags & MDB_RDONLY)) {
                void *p;
                p = (MDB_page *)(env->me_map + env->me_psize * pgno);
@@ -4272,7 +4272,7 @@ mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
                        size = meta->mm_mapsize;
                {
                        /* Silently round up to minimum if the size is too small */
-                       size_t minsize = (meta->mm_last_pg + 1) * env->me_psize;
+                       mdb_size_t minsize = (meta->mm_last_pg + 1) * env->me_psize;
                        if (size < minsize)
                                size = minsize;
                }
@@ -5830,7 +5830,7 @@ retry:
                                if (rc)
                                        goto fail;
                                if (!el[x].mref) {
-                                       munmap(el[x].mptr, el[x].mcnt);
+                                       munmap(el[x].mptr, env->me_psize * el[x].mcnt);
                                        el[x].mptr = id3.mptr;
                                        el[x].mcnt = id3.mcnt;
                                } else {
@@ -5882,36 +5882,15 @@ fail:
                        pthread_mutex_unlock(&env->me_rpmutex);
                        return rc;
                }
-               /* If this page is far enough from the end of the env, scan for
-                * any overflow pages that would spill onto another block.
-                * Note we must compare against mt_last_pgno, the last written
-                * page in the environment. Not mt_next_pgno, which increases
-                * for every newly allocated (but not yet written) page. If
-                * we scanned beyond the last written page we'd get a bus error.
-                */
-               if (pgno + MDB_RPAGE_CHUNK <= txn->mt_last_pgno) {
-                       int i;
-                       char *cp = (char *)id3.mptr + rem * env->me_psize;
-                       for (i=rem; i<MDB_RPAGE_CHUNK;) {
-                               p = (MDB_page *)cp;
-                               if (IS_OVERFLOW(p)) {
-                                       int nop = p->mp_pages;
-                                       if (nop + i > MDB_RPAGE_CHUNK) {
-                                               munmap(id3.mptr, len);
-                                               id3.mcnt = nop + i;
-                                               len = id3.mcnt * env->me_psize;
-                                               MAP(rc, env, id3.mptr, len, off);
-                                               if (rc)
-                                                       goto fail;
-                                               break;
-                                       }
-                                       i += nop;
-                                       cp += nop * env->me_psize;
-                               } else {
-                                       i++;
-                                       cp += env->me_psize;
-                               }
-                       }
+               /* check for overflow size */
+               p = (MDB_page *)((char *)id3.mptr + rem * env->me_psize);
+               if (IS_OVERFLOW(p) && p->mp_pages + rem > id3.mcnt) {
+                       id3.mcnt = p->mp_pages + rem;
+                       munmap(id3.mptr, len);
+                       len = id3.mcnt * env->me_psize;
+                       MAP(rc, env, id3.mptr, len, off);
+                       if (rc)
+                               goto fail;
                }
                mdb_mid3l_insert(el, &id3);
                pthread_mutex_unlock(&env->me_rpmutex);
@@ -6458,8 +6437,10 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
 
        DPRINTF(("cursor_next: top page is %"Y"u in cursor %p",
                mdb_dbg_pgno(mp), (void *) mc));
-       if (mc->mc_flags & C_DEL)
+       if (mc->mc_flags & C_DEL) {
+               mc->mc_flags ^= C_DEL;
                goto skip;
+       }
 
        if (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mp)) {
                DPUTS("=====> move to next sibling page");
@@ -6545,6 +6526,8 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
        DPRINTF(("cursor_prev: top page is %"Y"u in cursor %p",
                mdb_dbg_pgno(mp), (void *) mc));
 
+       mc->mc_flags &= ~(C_EOF|C_DEL);
+
        if (mc->mc_ki[mc->mc_top] == 0)  {
                DPUTS("=====> move to prev sibling page");
                if ((rc = mdb_cursor_sibling(mc, 0)) != MDB_SUCCESS) {
@@ -7562,7 +7545,7 @@ new_sub:
                 */
                if (do_sub) {
                        int xflags, new_dupdata;
-                       size_t ecount;
+                       mdb_size_t ecount;
 put_sub:
                        xdata.mv_size = 0;
                        xdata.mv_data = "";
@@ -8277,7 +8260,7 @@ mdb_cursor_renew(MDB_txn *txn, MDB_cursor *mc)
 
 /* Return the count of duplicate data items for the current key */
 int
-mdb_cursor_count(MDB_cursor *mc, size_t *countp)
+mdb_cursor_count(MDB_cursor *mc, mdb_size_t *countp)
 {
        MDB_node        *leaf;
 
@@ -10137,7 +10120,7 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
 #ifdef _WIN32
        rc = utf8_to_utf16(lpath, -1, &wpath, NULL);
        if (rc)
-               return rc;
+               goto leave;
        newfd = CreateFileW(wpath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
                                FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL);
        free(wpath);