diff --git a/mdb.c b/mdb.c index 374a5f8a..4f599dcb 100644 --- a/mdb.c +++ b/mdb.c @@ -9696,6 +9696,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi) MDB_db dummy; int rc, dbflag, exact; unsigned unused = 0, seq; + char *namedup; size_t len; if (unlikely(!txn || !dbi)) @@ -9764,8 +9765,16 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi) MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); if (unlikely((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)) return MDB_INCOMPATIBLE; - } else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) { - /* Create if requested */ + } else if (! (rc == MDB_NOTFOUND && (flags & MDB_CREATE))) { + return rc; + } + + /* Done here so we cannot fail after creating a new DB */ + if (unlikely((namedup = strdup(name)) == NULL)) + return ENOMEM; + + if (unlikely(rc)) { + /* MDB_NOTFOUND and MDB_CREATE: Create new DB */ data.mv_size = sizeof(MDB_db); data.mv_data = &dummy; memset(&dummy, 0, sizeof(dummy)); @@ -9775,10 +9784,12 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi) dbflag |= DB_DIRTY; } - /* OK, got info, add to table */ - if (likely(rc == MDB_SUCCESS)) { + if (unlikely(rc)) { + free(namedup); + } else { + /* Got info, register DBI in this txn */ unsigned slot = unused ? unused : txn->mt_numdbs; - txn->mt_dbxs[slot].md_name.mv_data = strdup(name); + txn->mt_dbxs[slot].md_name.mv_data = namedup; txn->mt_dbxs[slot].md_name.mv_size = len; txn->mt_dbxs[slot].md_rel = NULL; txn->mt_dbflags[slot] = dbflag;