https://bugs.openldap.org/show_bug.cgi?id=9723

          Issue ID: 9723
           Summary: C_EOF not reset in mdb_cursor_get with MDB_FIRST_DUP
           Product: LMDB
           Version: unspecified
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Keywords: needs_review
          Severity: normal
          Priority: ---
         Component: liblmdb
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

I'm on the master branch of lmdb.

Steps to reproduce

    // search for an non-existent key
    rc = mdb_cursor_get(cursor, &key, &val, MDB_SET_RANGE);
    if (rc == MDB_NOTFOUND) {
        // C_EOF is not set on the cursor flags

        // go to the last. 
        // C_EOF remains set which is ok
        mdb_cursor_get(mdbCursor, &key, &val, MDB_LAST);

        // go to the first dup of the last
        // C_EOF remains set which is NOT OK
        mdb_cursor_get(mdbCursor, &key, &val, MDB_FIRST_DUP);


        // return MDB_NOTFOUND in any case whether there are duplicates or not
        // because C_EOF was not cleared
        mdb_cursor_get(mdbCursor, &key, &val, MDB_NEXT_NODUP);
    }


Possible fix:

    case MDB_FIRST_DUP:
        mfunc = mdb_cursor_first;
    mmove:
        if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
            rc = EINVAL;
            break;
        }
        if (mc->mc_xcursor == NULL) {
            rc = MDB_INCOMPATIBLE;
            break;
        }
        if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) {
            mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]);
            rc = MDB_NOTFOUND;
            break;
        }
        {
            MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top],
mc->mc_ki[mc->mc_top]);
            if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
                MDB_GET_KEY(leaf, key);
                rc = mdb_node_read(mc, leaf, data);
                break;
            }
        }
        if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
            rc = EINVAL;
            break;
        }
        rc = mfunc(&mc->mc_xcursor->mx_cursor, data, NULL);
        // FIX: clear C_EOF
        if (rc == MDB_SUCCESS && mc->mc_flags & C_EOF && mfunc ==
mdb_cursor_first) {
            mc->mc_flags ^= C_EOF;
        }
        break;

-- 
You are receiving this mail because:
You are on the CC list for the issue.

Reply via email to