diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt index a3d70f0d3..dcd25505a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt @@ -51,12 +51,6 @@ class DatabaseKDB : DatabaseVersioned() { kdfListV3.add(KdfFactory.aesKdf) } - private fun getGroupById(groupId: Int): GroupKDB? { - if (groupId == -1) - return null - return getGroupById(NodeIdInt(groupId)) - } - val backupGroup: GroupKDB? get() { return retrieveBackup() @@ -81,11 +75,6 @@ class DatabaseKDB : DatabaseVersioned() { return list } - val rootGroups: List - get() { - return rootGroup?.getChildGroups() ?: ArrayList() - } - override val passwordEncoding: String get() = "ISO-8859-1" diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt index e42570881..427532a0a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt @@ -414,37 +414,37 @@ class DatabaseKDBX : DatabaseVersioned { } fun getEntryByTitle(title: String, recursionLevel: Int): EntryKDBX? { - return this.entryIndexes.values.find { entry -> + return findEntry { entry -> entry.decodeTitleKey(recursionLevel).equals(title, true) } } fun getEntryByUsername(username: String, recursionLevel: Int): EntryKDBX? { - return this.entryIndexes.values.find { entry -> + return findEntry { entry -> entry.decodeUsernameKey(recursionLevel).equals(username, true) } } fun getEntryByURL(url: String, recursionLevel: Int): EntryKDBX? { - return this.entryIndexes.values.find { entry -> + return findEntry { entry -> entry.decodeUrlKey(recursionLevel).equals(url, true) } } fun getEntryByPassword(password: String, recursionLevel: Int): EntryKDBX? { - return this.entryIndexes.values.find { entry -> + return findEntry { entry -> entry.decodePasswordKey(recursionLevel).equals(password, true) } } fun getEntryByNotes(notes: String, recursionLevel: Int): EntryKDBX? { - return this.entryIndexes.values.find { entry -> + return findEntry { entry -> entry.decodeNotesKey(recursionLevel).equals(notes, true) } } fun getEntryByCustomData(customDataValue: String): EntryKDBX? { - return entryIndexes.values.find { entry -> + return findEntry { entry -> entry.customData.containsItemWithValue(customDataValue) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt index a61073592..61d3a3e40 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt @@ -67,7 +67,7 @@ abstract class DatabaseVersioned< var changeDuplicateId = false private var groupIndexes = LinkedHashMap, Group>() - protected var entryIndexes = LinkedHashMap, Entry>() + private var entryIndexes = LinkedHashMap, Entry>() abstract val version: String @@ -199,12 +199,6 @@ abstract class DatabaseVersioned< * ------------------------------------- */ - fun doForEachGroupInIndex(action: (Group) -> Unit) { - for (group in groupIndexes) { - action.invoke(group.value) - } - } - /** * Determine if an id number is already in use * @@ -220,14 +214,7 @@ abstract class DatabaseVersioned< return groupIndexes.values } - fun setGroupIndexes(groupList: List) { - this.groupIndexes.clear() - for (currentGroup in groupList) { - this.groupIndexes[currentGroup.nodeId] = currentGroup - } - } - - fun getGroupById(id: NodeId): Group? { + open fun getGroupById(id: NodeId): Group? { return this.groupIndexes[id] } @@ -251,16 +238,6 @@ abstract class DatabaseVersioned< this.groupIndexes.remove(group.nodeId) } - fun numberOfGroups(): Int { - return groupIndexes.size - } - - fun doForEachEntryInIndex(action: (Entry) -> Unit) { - for (entry in entryIndexes) { - action.invoke(entry.value) - } - } - fun isEntryIdUsed(id: NodeId): Boolean { return entryIndexes.containsKey(id) } @@ -273,6 +250,10 @@ abstract class DatabaseVersioned< return this.entryIndexes[id] } + fun findEntry(predicate: (Entry) -> Boolean): Entry? { + return this.entryIndexes.values.find(predicate) + } + fun addEntryIndex(entry: Entry) { val entryId = entry.nodeId if (entryIndexes.containsKey(entryId)) { @@ -293,10 +274,6 @@ abstract class DatabaseVersioned< this.entryIndexes.remove(entry.nodeId) } - fun numberOfEntries(): Int { - return entryIndexes.size - } - open fun clearCache() { this.groupIndexes.clear() this.entryIndexes.clear() diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt index 70e51b39a..a3f866d97 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt @@ -22,6 +22,7 @@ package com.kunzisoft.keepass.database.file.output import com.kunzisoft.encrypt.HashManager import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm import com.kunzisoft.keepass.database.element.database.DatabaseKDB +import com.kunzisoft.keepass.database.element.entry.EntryKDB import com.kunzisoft.keepass.database.element.group.GroupKDB import com.kunzisoft.keepass.database.exception.DatabaseOutputException import com.kunzisoft.keepass.database.file.DatabaseHeader @@ -34,7 +35,6 @@ import java.io.ByteArrayOutputStream import java.io.IOException import java.io.OutputStream import java.security.* -import java.util.* import javax.crypto.Cipher import javax.crypto.CipherOutputStream @@ -44,6 +44,9 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, private var headerHashBlock: ByteArray? = null + private var mGroupList = mutableListOf() + private var mEntryList = mutableListOf() + @Throws(DatabaseOutputException::class) fun getFinalKey(header: DatabaseHeader): ByteArray? { try { @@ -61,7 +64,7 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, // and remove any orphaned nodes that are no longer part of the tree hierarchy // also remove the virtual root not present in kdb val rootGroup = mDatabaseKDB.rootGroup - sortGroupsForOutput() + sortNodesForOutput() val header = outputHeader(mOutputStream) @@ -91,6 +94,8 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, } finally { // Add again the virtual root group for better management mDatabaseKDB.rootGroup = rootGroup + mGroupList.clear() + mEntryList.clear() } } @@ -120,8 +125,9 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, } header.version = DatabaseHeaderKDB.DBVER_DW - header.numGroups = UnsignedInt(mDatabaseKDB.numberOfGroups()) - header.numEntries = UnsignedInt(mDatabaseKDB.numberOfEntries()) + // To remove root + header.numGroups = UnsignedInt(mGroupList.size) + header.numEntries = UnsignedInt(mEntryList.size) header.numKeyEncRounds = UnsignedInt.fromKotlinLong(mDatabaseKDB.numberKeyEncryptionRounds) setIVs(header) @@ -194,31 +200,40 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, } // Groups - mDatabaseKDB.doForEachGroupInIndex { group -> - GroupOutputKDB(group, outputStream).output() + mGroupList.forEach { group -> + if (group != mDatabaseKDB.rootGroup) { + GroupOutputKDB(group, outputStream).output() + } } // Entries - mDatabaseKDB.doForEachEntryInIndex { entry -> + mEntryList.forEach { entry -> EntryOutputKDB(mDatabaseKDB, entry, outputStream).output() } } - private fun sortGroupsForOutput() { - val groupList = ArrayList() + private fun sortNodesForOutput() { + mGroupList.clear() + mEntryList.clear() // Rebuild list according to sorting order removing any orphaned groups - for (rootGroup in mDatabaseKDB.rootGroups) { - sortGroup(rootGroup, groupList) + // Do not keep root + mDatabaseKDB.rootGroup?.getChildGroups()?.let { rootSubGroups -> + for (rootGroup in rootSubGroups) { + sortGroup(rootGroup) + } } - mDatabaseKDB.setGroupIndexes(groupList) } - private fun sortGroup(group: GroupKDB, groupList: MutableList) { + private fun sortGroup(group: GroupKDB) { // Add current tree - groupList.add(group) + mGroupList.add(group) + + for (childEntry in group.getChildEntries()) { + mEntryList.add(childEntry) + } // Recurse over children for (childGroup in group.getChildGroups()) { - sortGroup(childGroup, groupList) + sortGroup(childGroup) } }