]> git.sur5r.net Git - openldap/commitdiff
ITS#7793 mdb_cursor_put(): Fix MDB_CURRENT.
authorHallvard Furuseth <hallvard@openldap.org>
Tue, 28 Jan 2014 13:27:27 +0000 (14:27 +0100)
committerHallvard Furuseth <hallvard@openldap.org>
Tue, 28 Jan 2014 13:27:27 +0000 (14:27 +0100)
Ignore key, broken by 5bda3565a9bfaa6cd54053faeafcc06da15bc00c
and some older code.  Document and clarify MDB_CURRENT usage.

Also affects non-MDB_CURRENT put() with empty data and a key
which matches by the mdb_set_compare function but not by memcmp.

libraries/liblmdb/lmdb.h
libraries/liblmdb/mdb.c

index 2ebd43f3daedf7817786deaddfb7f97821e168d9..2ece80580d02b99ae3c3528a786e09103474318b 100644 (file)
@@ -1333,7 +1333,7 @@ int  mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
         * <ul>
         *      <li>#MDB_CURRENT - overwrite the data of the key/data pair to which
         *              the cursor refers with the specified data item. The \b key
-        *              parameter is ignored.
+        *              parameter is ignored.  The \b data size must match the original.
         *      <li>#MDB_NODUPDATA - enter the new key/data pair only if it does not
         *              already appear in the database. This flag may only be specified
         *              if the database was opened with #MDB_DUPSORT. The function will
index 7e2905891eb770c4d6eb53f751bd05b2738a0c7a..5a607a4c7e96d0324ec7086036f660191cca42fb 100644 (file)
@@ -2728,10 +2728,11 @@ mdb_freelist_save(MDB_txn *txn)
                        MDB_ID save;
 
                        mdb_tassert(txn, len >= 0 && id <= env->me_pglast);
-                       key.mv_data = &id;
                        if (len > mop_len) {
                                len = mop_len;
                                data.mv_size = (len + 1) * sizeof(MDB_ID);
+                               /* Drop MDB_CURRENT when changing the data size */
+                               key.mv_data = &id;
                                flags = 0;
                        }
                        data.mv_data = mop -= len;
@@ -5761,7 +5762,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        unsigned int nflags;
        DKBUF;
 
-       if (mc == NULL || key == NULL)
+       if (mc == NULL)
                return EINVAL;
 
        env = mc->mc_txn->mt_env;
@@ -5782,8 +5783,16 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
                return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
 
-       if (flags != MDB_CURRENT && key->mv_size-1 >= ENV_MAXKEY(env))
-               return MDB_BAD_VALSIZE;
+       if (flags != MDB_CURRENT) {
+               if (key == NULL)
+                       return EINVAL;
+               if (key->mv_size-1 >= ENV_MAXKEY(env))
+                       return MDB_BAD_VALSIZE;
+       } else {
+               /* Ignore key except in sub-cursor, where key holds the data */
+               if (!(mc->mc_flags & C_SUB))
+                       key = NULL;
+       }
 
 #if SIZE_MAX > MAXDATASIZE
        if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE))
@@ -6107,7 +6116,7 @@ current:
                         */
                        if (F_ISSET(flags, MDB_RESERVE))
                                data->mv_data = olddata.mv_data;
-                       else if (data->mv_size)
+                       else if (!(mc->mc_flags & C_SUB))
                                memcpy(olddata.mv_data, data->mv_data, data->mv_size);
                        else
                                memcpy(NODEKEY(leaf), key->mv_data, key->mv_size);