Commit 200ab98f authored by Howard Chu's avatar Howard Chu
Browse files

Fix ITS#402 - index corruption in idl_insert_key

parent e2fa96f2
......@@ -478,18 +478,52 @@ idl_insert_key(
/* is there a next block? */
if ( !first && !ID_BLOCK_NOID(idl, i + 1) ) {
/* read it in */
sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr,
k2.dptr = (char *) ch_malloc( key.dsize + 20 );
sprintf( k2.dptr, "%c%s%ld", CONT_PREFIX, key.dptr,
ID_BLOCK_ID(idl, i + 1) );
k2.dptr = kstr;
k2.dsize = strlen( kstr ) + 1;
k2.dsize = strlen( k2.dptr ) + 1;
if ( (tmp2 = idl_fetch_one( be, db, k2 )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"idl_fetch_one (%s) returns NULL\n",
k2.dptr, 0, 0 );
/* split the original block */
free( k2.dptr );
goto split;
}
/* If the new id is less than the last id in the
* current block, it must not be put into the next
* block. Push the last id of the current block
* into the next block instead.
*/
if (id < ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1)) {
ID id2 = ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp) - 1);
Datum k3;
ldbm_datum_init( k3 );
--ID_BLOCK_NIDS(tmp);
/* This must succeed since we just popped one
* ID off the end of it.
*/
rc = idl_insert( &tmp, id, db->dbc_maxids );
assert( rc == 0 );
k3.dptr = kstr;
k3.dsize = strlen( kstr ) + 1;
if ( (rc = idl_store( be, db, k3, tmp )) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"idl_store of (%s) returns %d\n", k3.dptr, rc, 0 );
}
free( kstr );
kstr = k2.dptr;
id = id2;
/* This new id will necessarily be inserted
* as the first id of the next block by the
* following switch() statement.
*/
}
switch ( (rc = idl_insert( &tmp2, id,
db->dbc_maxids )) ) {
case 1: /* id inserted first in block */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment