First commit to allocate dynamic memory

This commit is contained in:
J-Jamet
2021-03-23 13:07:49 +01:00
parent 492382d552
commit 520c6b60be
17 changed files with 105 additions and 129 deletions

View File

@@ -25,6 +25,7 @@ import com.kunzisoft.keepass.app.database.CipherDatabaseAction
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.BinaryData
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
import com.kunzisoft.keepass.model.MainCredential
import com.kunzisoft.keepass.settings.PreferencesUtil
@@ -55,6 +56,9 @@ class LoadDatabaseRunnable(private val context: Context,
mReadonly,
context.contentResolver,
UriUtil.getBinaryDir(context),
{ memoryWanted ->
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
},
Database.LoadedKey.generateNewCipherKey(),
mFixDuplicateUUID,
progressTaskUpdater)

View File

@@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.action
import android.content.Context
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.BinaryData
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable
@@ -46,6 +47,9 @@ class ReloadDatabaseRunnable(private val context: Context,
try {
mDatabase.reloadData(context.contentResolver,
UriUtil.getBinaryDir(context),
{ memoryWanted ->
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
},
tempCipherKey ?: Database.LoadedKey.generateNewCipherKey(),
progressTaskUpdater)
} catch (e: LoadDatabaseException) {

View File

@@ -30,12 +30,15 @@ data class Attachment(var name: String,
constructor(parcel: Parcel) : this(
parcel.readString() ?: "",
parcel.readParcelable(BinaryData::class.java.classLoader) ?: BinaryByte()
// TODO BinaryParcelable
//parcel.readParcelable(BinaryData::class.java.classLoader) ?:
BinaryByte()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeParcelable(binaryData, flags)
// TODO BinaryParcelable
//parcel.writeParcelable(binaryData, flags)
}
override fun describeContents(): Int {

View File

@@ -453,6 +453,7 @@ class Database {
readOnly: Boolean,
contentResolver: ContentResolver,
cacheDirectory: File,
isRAMSufficient: (memoryWanted: Long) -> Boolean,
tempCipherKey: LoadedKey,
fixDuplicateUUID: Boolean,
progressTaskUpdater: ProgressTaskUpdater?) {
@@ -474,7 +475,7 @@ class Database {
// Read database stream for the first time
readDatabaseStream(contentResolver, uri,
{ databaseInputStream ->
DatabaseInputKDB(cacheDirectory)
DatabaseInputKDB(cacheDirectory, isRAMSufficient)
.openDatabase(databaseInputStream,
mainCredential.masterPassword,
keyFileInputStream,
@@ -483,7 +484,7 @@ class Database {
fixDuplicateUUID)
},
{ databaseInputStream ->
DatabaseInputKDBX(cacheDirectory)
DatabaseInputKDBX(cacheDirectory, isRAMSufficient)
.openDatabase(databaseInputStream,
mainCredential.masterPassword,
keyFileInputStream,
@@ -507,6 +508,7 @@ class Database {
@Throws(LoadDatabaseException::class)
fun reloadData(contentResolver: ContentResolver,
cacheDirectory: File,
isRAMSufficient: (memoryWanted: Long) -> Boolean,
tempCipherKey: LoadedKey,
progressTaskUpdater: ProgressTaskUpdater?) {
@@ -515,14 +517,14 @@ class Database {
fileUri?.let { oldDatabaseUri ->
readDatabaseStream(contentResolver, oldDatabaseUri,
{ databaseInputStream ->
DatabaseInputKDB(cacheDirectory)
DatabaseInputKDB(cacheDirectory, isRAMSufficient)
.openDatabase(databaseInputStream,
masterKey,
tempCipherKey,
progressTaskUpdater)
},
{ databaseInputStream ->
DatabaseInputKDBX(cacheDirectory)
DatabaseInputKDBX(cacheDirectory, isRAMSufficient)
.openDatabase(databaseInputStream,
masterKey,
tempCipherKey,
@@ -576,8 +578,7 @@ class Database {
val attachmentPool: AttachmentPool
get() {
// Binary pool is functionally only in KDBX
return mDatabaseKDBX?.binaryPool ?: AttachmentPool()
return mDatabaseKDB?.binaryPool ?: mDatabaseKDBX?.binaryPool ?: AttachmentPool()
}
val allowMultipleAttachments: Boolean
@@ -593,7 +594,7 @@ class Database {
compressed: Boolean = false,
protected: Boolean = false): BinaryData? {
return mDatabaseKDB?.buildNewAttachment(cacheDirectory)
?: mDatabaseKDBX?.buildNewAttachment(cacheDirectory, compressed, protected)
?: mDatabaseKDBX?.buildNewAttachment(cacheDirectory, false, compressed, protected)
}
fun removeAttachmentIfNotUsed(attachment: Attachment) {

View File

@@ -311,7 +311,7 @@ class Entry : Node, EntryVersionedInterface<Group> {
fun getAttachments(attachmentPool: AttachmentPool, inHistory: Boolean = false): List<Attachment> {
val attachments = ArrayList<Attachment>()
entryKDB?.getAttachment()?.let {
entryKDB?.getAttachment(attachmentPool)?.let {
attachments.add(it)
}
entryKDBX?.getAttachments(attachmentPool, inHistory)?.let {
@@ -336,7 +336,7 @@ class Entry : Node, EntryVersionedInterface<Group> {
}
private fun putAttachment(attachment: Attachment, attachmentPool: AttachmentPool) {
entryKDB?.putAttachment(attachment)
entryKDB?.putAttachment(attachment, attachmentPool)
entryKDBX?.putAttachment(attachment, attachmentPool)
}

View File

@@ -19,8 +19,6 @@
*/
package com.kunzisoft.keepass.database.element.database
import android.os.Parcel
import android.os.Parcelable
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.stream.readAllBytes
import java.io.*
@@ -35,18 +33,15 @@ class BinaryByte : BinaryData {
*/
constructor() : super()
constructor(compressed: Boolean = false,
protected: Boolean = false) : super(compressed, protected)
constructor(byteArray: ByteArray,
compressed: Boolean = false,
protected: Boolean = false) : super(compressed, protected) {
this.mDataByte = byteArray
}
constructor(parcel: Parcel) : super(parcel) {
val byteArray = ByteArray(parcel.readInt())
parcel.readByteArray(byteArray)
mDataByte = byteArray
}
@Throws(IOException::class)
override fun getInputDataStream(cipherKey: Database.LoadedKey): InputStream {
return ByteArrayInputStream(mDataByte)
@@ -112,12 +107,6 @@ class BinaryByte : BinaryData {
return mDataByte.toString()
}
override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags)
dest.writeInt(mDataByte.size)
dest.writeByteArray(mDataByte)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is BinaryByte) return false
@@ -145,21 +134,7 @@ class BinaryByte : BinaryData {
}
companion object {
private val TAG = BinaryByte::class.java.name
// Max Parcelable / 2
const val MAX_BINARY_BYTES = 524288
@JvmField
val CREATOR: Parcelable.Creator<BinaryByte> = object : Parcelable.Creator<BinaryByte> {
override fun createFromParcel(parcel: Parcel): BinaryByte {
return BinaryByte(parcel)
}
override fun newArray(size: Int): Array<BinaryByte?> {
return arrayOfNulls(size)
}
}
}
}

View File

@@ -19,8 +19,8 @@
*/
package com.kunzisoft.keepass.database.element.database
import android.os.Parcel
import android.os.Parcelable
import android.app.ActivityManager
import android.content.Context
import com.kunzisoft.keepass.database.element.Database
import java.io.IOException
import java.io.InputStream
@@ -28,7 +28,7 @@ import java.io.OutputStream
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
abstract class BinaryData : Parcelable {
abstract class BinaryData {
var isCompressed: Boolean = false
protected set
@@ -46,12 +46,6 @@ abstract class BinaryData : Parcelable {
this.isProtected = protected
}
protected constructor(parcel: Parcel) {
isCompressed = parcel.readByte().toInt() != 0
isProtected = parcel.readByte().toInt() != 0
isCorrupted = parcel.readByte().toInt() != 0
}
@Throws(IOException::class)
abstract fun getInputDataStream(cipherKey: Database.LoadedKey): InputStream
@@ -91,16 +85,6 @@ abstract class BinaryData : Parcelable {
abstract fun binaryHash(): Int
override fun describeContents(): Int {
return 0
}
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeByte((if (isCompressed) 1 else 0).toByte())
dest.writeByte((if (isProtected) 1 else 0).toByte())
dest.writeByte((if (isCorrupted) 1 else 0).toByte())
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is BinaryData) return false
@@ -121,6 +105,13 @@ abstract class BinaryData : Parcelable {
companion object {
private val TAG = BinaryData::class.java.name
fun canMemoryBeAllocatedInRAM(context: Context, memoryWanted: Long): Boolean {
val memoryInfo = ActivityManager.MemoryInfo()
(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).getMemoryInfo(memoryInfo)
val availableMemory = memoryInfo.availMem
return availableMemory > memoryWanted * 3
}
}
}

View File

@@ -19,8 +19,6 @@
*/
package com.kunzisoft.keepass.database.element.database
import android.os.Parcel
import android.os.Parcelable
import android.util.Base64
import android.util.Base64InputStream
import android.util.Base64OutputStream
@@ -57,14 +55,6 @@ class BinaryFile : BinaryData {
this.mBinaryHash = 0
}
constructor(parcel: Parcel) : super(parcel) {
parcel.readString()?.let {
mDataFile = File(it)
}
mLength = parcel.readLong()
mBinaryHash = parcel.readInt()
}
@Throws(IOException::class)
override fun getInputDataStream(cipherKey: Database.LoadedKey): InputStream {
return buildInputStream(mDataFile, cipherKey)
@@ -172,13 +162,6 @@ class BinaryFile : BinaryData {
return mDataFile.toString()
}
override fun writeToParcel(dest: Parcel, flags: Int) {
super.writeToParcel(dest, flags)
dest.writeString(mDataFile?.absolutePath)
dest.writeLong(mLength)
dest.writeInt(mBinaryHash)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is BinaryFile) return false
@@ -236,19 +219,7 @@ class BinaryFile : BinaryData {
}
companion object {
private val TAG = BinaryFile::class.java.name
@JvmField
val CREATOR: Parcelable.Creator<BinaryFile> = object : Parcelable.Creator<BinaryFile> {
override fun createFromParcel(parcel: Parcel): BinaryFile {
return BinaryFile(parcel)
}
override fun newArray(size: Int): Array<BinaryFile?> {
return arrayOfNulls(size)
}
}
}
}

View File

@@ -46,7 +46,7 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
private var kdfListV3: MutableList<KdfEngine> = ArrayList()
// Only to generate unique file name
private var binaryPool = AttachmentPool()
var binaryPool = AttachmentPool()
override val version: String
get() = "KeePass 1"

View File

@@ -318,9 +318,9 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
fun addCustomIcon(cacheDirectory: File,
customIconId: UUID? = null,
dataSize: Int,
smallSize: Boolean,
result: (IconImageCustom, BinaryData?) -> Unit) {
iconsManager.addCustomIcon(cacheDirectory, customIconId, dataSize, result)
iconsManager.addCustomIcon(cacheDirectory, customIconId, smallSize, result)
}
fun isCustomIconBinaryDuplicate(binary: BinaryData): Boolean {
@@ -642,12 +642,17 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
}
fun buildNewAttachment(cacheDirectory: File,
smallSize: Boolean,
compression: Boolean,
protection: Boolean,
binaryPoolId: Int? = null): BinaryData {
return binaryPool.put(binaryPoolId) { uniqueBinaryId ->
val fileInCache = File(cacheDirectory, uniqueBinaryId)
BinaryFile(fileInCache, compression, protection)
if (smallSize) {
BinaryByte(compression, protection)
} else {
val fileInCache = File(cacheDirectory, uniqueBinaryId)
BinaryFile(fileInCache, compression, protection)
}
}.binary
}

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.database.element.entry
import android.os.Parcel
import android.os.Parcelable
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.database.AttachmentPool
import com.kunzisoft.keepass.database.element.database.BinaryData
import com.kunzisoft.keepass.database.element.group.GroupKDB
import com.kunzisoft.keepass.database.element.icon.IconImageStandard.Companion.KEY_ID
@@ -56,7 +57,7 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
/** A string describing what is in binaryData */
var binaryDescription = ""
var binaryData: BinaryData? = null
private var binaryDataId: Int? = null
// Determine if this is a MetaStream entry
val isMetaStream: Boolean
@@ -89,7 +90,7 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
url = parcel.readString() ?: url
notes = parcel.readString() ?: notes
binaryDescription = parcel.readString() ?: binaryDescription
binaryData = parcel.readParcelable(BinaryData::class.java.classLoader)
binaryDataId = parcel.readInt()
}
override fun readParentParcelable(parcel: Parcel): GroupKDB? {
@@ -108,7 +109,9 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
dest.writeString(url)
dest.writeString(notes)
dest.writeString(binaryDescription)
dest.writeParcelable(binaryData, flags)
binaryDataId?.let {
dest.writeInt(it)
}
}
fun updateWith(source: EntryKDB) {
@@ -119,7 +122,7 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
url = source.url
notes = source.notes
binaryDescription = source.binaryDescription
binaryData = source.binaryData
binaryDataId = source.binaryDataId
}
override var username = ""
@@ -138,26 +141,39 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
override val type: Type
get() = Type.ENTRY
fun getAttachment(): Attachment? {
val binary = binaryData
return if (binary != null)
Attachment(binaryDescription, binary)
else null
fun getAttachment(attachmentPool: AttachmentPool): Attachment? {
binaryDataId?.let { poolId ->
attachmentPool[poolId]?.let { binary ->
return Attachment(binaryDescription, binary)
}
}
return null
}
fun containsAttachment(): Boolean {
return binaryData != null
return binaryDataId != null
}
fun putAttachment(attachment: Attachment) {
fun getBinary(attachmentPool: AttachmentPool): BinaryData? {
this.binaryDataId?.let {
return attachmentPool[it]
}
return null
}
fun putBinary(binaryData: BinaryData, attachmentPool: AttachmentPool) {
this.binaryDataId = attachmentPool.put(binaryData)
}
fun putAttachment(attachment: Attachment, attachmentPool: AttachmentPool) {
this.binaryDescription = attachment.name
this.binaryData = attachment.binaryData
this.binaryDataId = attachmentPool.put(attachment.binaryData)
}
fun removeAttachment(attachment: Attachment? = null) {
if (attachment == null || this.binaryDescription == attachment.name) {
this.binaryDescription = ""
this.binaryData = null
this.binaryDataId = null
}
}

View File

@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.database.element.icon
import android.util.Log
import com.kunzisoft.keepass.database.element.database.BinaryByte
import com.kunzisoft.keepass.database.element.database.BinaryByte.Companion.MAX_BINARY_BYTES
import com.kunzisoft.keepass.database.element.database.BinaryData
import com.kunzisoft.keepass.database.element.database.BinaryFile
import com.kunzisoft.keepass.database.element.database.CustomIconPool
@@ -56,16 +55,16 @@ class IconsManager {
key: UUID? = null,
result: (IconImageCustom, BinaryData?) -> Unit) {
// Create a binary file for a brand new custom icon
addCustomIcon(cacheDirectory, key, -1, result)
addCustomIcon(cacheDirectory, key, false, result)
}
fun addCustomIcon(cacheDirectory: File,
key: UUID? = null,
dataSize: Int,
smallSize: Boolean,
result: (IconImageCustom, BinaryData?) -> Unit) {
val keyBinary = customCache.put(key) { uniqueBinaryId ->
// Create a byte array for better performance with small data
if (dataSize in 1..MAX_BINARY_BYTES) {
if (smallSize) {
BinaryByte()
} else {
val fileInCache = File(cacheDirectory, uniqueBinaryId)

View File

@@ -26,8 +26,9 @@ import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import java.io.File
import java.io.InputStream
abstract class DatabaseInput<PwDb : DatabaseVersioned<*, *, *, *>>
(protected val cacheDirectory: File) {
abstract class DatabaseInput<D : DatabaseVersioned<*, *, *, *>>
(protected val cacheDirectory: File,
protected val isRAMSufficient: (memoryWanted: Long) -> Boolean) {
/**
* Load a versioned database file, return contents in a new DatabaseVersioned.
@@ -45,7 +46,7 @@ abstract class DatabaseInput<PwDb : DatabaseVersioned<*, *, *, *>>
keyfileInputStream: InputStream?,
loadedCipherKey: Database.LoadedKey,
progressTaskUpdater: ProgressTaskUpdater?,
fixDuplicateUUID: Boolean = false): PwDb
fixDuplicateUUID: Boolean = false): D
@Throws(LoadDatabaseException::class)
@@ -53,5 +54,5 @@ abstract class DatabaseInput<PwDb : DatabaseVersioned<*, *, *, *>>
masterKey: ByteArray,
loadedCipherKey: Database.LoadedKey,
progressTaskUpdater: ProgressTaskUpdater?,
fixDuplicateUUID: Boolean = false): PwDb
fixDuplicateUUID: Boolean = false): D
}

View File

@@ -46,8 +46,9 @@ import javax.crypto.spec.SecretKeySpec
/**
* Load a KDB database file.
*/
class DatabaseInputKDB(cacheDirectory: File)
: DatabaseInput<DatabaseKDB>(cacheDirectory) {
class DatabaseInputKDB(cacheDirectory: File,
isRAMSufficient: (memoryWanted: Long) -> Boolean)
: DatabaseInput<DatabaseKDB>(cacheDirectory, isRAMSufficient) {
private lateinit var mDatabase: DatabaseKDB
@@ -306,11 +307,11 @@ class DatabaseInputKDB(cacheDirectory: File)
0x000E -> {
newEntry?.let { entry ->
if (fieldSize > 0) {
val binaryAttachment = mDatabase.buildNewAttachment(cacheDirectory)
entry.binaryData = binaryAttachment
val binaryData = mDatabase.buildNewAttachment(cacheDirectory)
entry.putBinary(binaryData, mDatabase.binaryPool)
val cipherKey = mDatabase.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to load binaries")
BufferedOutputStream(binaryAttachment.getOutputDataStream(cipherKey)).use { outputStream ->
BufferedOutputStream(binaryData.getOutputDataStream(cipherKey)).use { outputStream ->
cipherInputStream.readBytes(fieldSize) { buffer ->
outputStream.write(buffer)
}

View File

@@ -63,8 +63,9 @@ import javax.crypto.Cipher
import javax.crypto.CipherInputStream
import kotlin.math.min
class DatabaseInputKDBX(cacheDirectory: File)
: DatabaseInput<DatabaseKDBX>(cacheDirectory) {
class DatabaseInputKDBX(cacheDirectory: File,
isRAMSufficient: (memoryWanted: Long) -> Boolean)
: DatabaseInput<DatabaseKDBX>(cacheDirectory, isRAMSufficient) {
private var randomStream: StreamCipher? = null
private lateinit var mDatabase: DatabaseKDBX
@@ -276,7 +277,8 @@ class DatabaseInputKDBX(cacheDirectory: File)
val protectedFlag = dataInputStream.read().toByte() == DatabaseHeaderKDBX.KdbxBinaryFlags.Protected
val byteLength = size - 1
// No compression at this level
val protectedBinary = mDatabase.buildNewAttachment(cacheDirectory, false, protectedFlag)
val protectedBinary = mDatabase.buildNewAttachment(cacheDirectory,
isRAMSufficient.invoke(byteLength.toLong()), false, protectedFlag)
val cipherKey = mDatabase.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to load binaries")
protectedBinary.getOutputDataStream(cipherKey).use { outputStream ->
@@ -703,11 +705,12 @@ class DatabaseInputKDBX(cacheDirectory: File)
} else if (ctx == KdbContext.CustomIcons && name.equals(DatabaseKDBXXML.ElemCustomIcons, ignoreCase = true)) {
return KdbContext.Meta
} else if (ctx == KdbContext.CustomIcon && name.equals(DatabaseKDBXXML.ElemCustomIconItem, ignoreCase = true)) {
if (customIconID != DatabaseVersioned.UUID_ZERO && customIconData != null) {
mDatabase.addCustomIcon(cacheDirectory, customIconID, customIconData!!.size) { _, binary ->
val iconData = customIconData
if (customIconID != DatabaseVersioned.UUID_ZERO && iconData != null) {
mDatabase.addCustomIcon(cacheDirectory, customIconID, isRAMSufficient.invoke(iconData.size.toLong())) { _, binary ->
mDatabase.loadedCipherKey?.let { cipherKey ->
binary?.getOutputDataStream(cipherKey)?.use { outputStream ->
outputStream.write(customIconData)
outputStream.write(iconData)
}
}
}
@@ -981,7 +984,7 @@ class DatabaseInputKDBX(cacheDirectory: File)
var binaryRetrieve = mDatabase.binaryPool[id]
// Create empty binary if not retrieved in pool
if (binaryRetrieve == null) {
binaryRetrieve = mDatabase.buildNewAttachment(cacheDirectory,
binaryRetrieve = mDatabase.buildNewAttachment(cacheDirectory, false,
compression = false, protection = false, binaryPoolId = id)
}
return binaryRetrieve
@@ -1018,7 +1021,8 @@ class DatabaseInputKDBX(cacheDirectory: File)
return null
// Build the new binary and compress
val binaryAttachment = mDatabase.buildNewAttachment(cacheDirectory, compressed, protected, binaryId)
val binaryAttachment = mDatabase.buildNewAttachment(cacheDirectory,
isRAMSufficient.invoke(base64.length.toLong()), compressed, protected, binaryId)
val binaryCipherKey = mDatabase.loadedCipherKey
?: throw IOException("Unable to retrieve cipher key to load binaries")
try {

View File

@@ -217,7 +217,7 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
}
// Entries
mDatabaseKDB.doForEachEntryInIndex { entry ->
EntryOutputKDB(entry, outputStream, mDatabaseKDB.loadedCipherKey).output()
EntryOutputKDB(entry, outputStream, mDatabaseKDB.loadedCipherKey).output(mDatabaseKDB)
}
}

View File

@@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.file.output
import android.util.Log
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.entry.EntryKDB
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
import com.kunzisoft.keepass.stream.*
@@ -39,7 +40,7 @@ class EntryOutputKDB(private val mEntry: EntryKDB,
//NOTE: Need be to careful about using ints. The actual type written to file is a unsigned int
@Throws(DatabaseOutputException::class)
fun output() {
fun output(database: DatabaseKDB) {
try {
// UUID
mOutputStream.write(UUID_FIELD_TYPE)
@@ -96,7 +97,7 @@ class EntryOutputKDB(private val mEntry: EntryKDB,
// Binary
mCipherKey?.let { cipherKey ->
mOutputStream.write(BINARY_DATA_FIELD_TYPE)
val binaryData = mEntry.binaryData
val binaryData = mEntry.getBinary(database.binaryPool)
val binaryDataLength = binaryData?.getSize() ?: 0L
// Write data length
mOutputStream.write(uIntTo4Bytes(UnsignedInt.fromKotlinLong(binaryDataLength)))