mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix OOM #256
This commit is contained in:
@@ -22,7 +22,7 @@ package com.kunzisoft.keepass.database.element
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
@@ -48,7 +48,7 @@ class AutoType : Parcelable {
|
||||
this.enabled = parcel.readByte().toInt() != 0
|
||||
this.obfuscationOptions = parcel.readLong()
|
||||
this.defaultSequence = parcel.readString()
|
||||
this.windowSeqPairs = MemUtil.readStringParcelableMap(parcel)
|
||||
this.windowSeqPairs = MemoryUtil.readStringParcelableMap(parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
@@ -59,7 +59,7 @@ class AutoType : Parcelable {
|
||||
dest.writeByte((if (enabled) 1 else 0).toByte())
|
||||
dest.writeLong(obfuscationOptions)
|
||||
dest.writeString(defaultSequence)
|
||||
MemUtil.writeStringParcelableMap(dest, windowSeqPairs)
|
||||
MemoryUtil.writeStringParcelableMap(dest, windowSeqPairs)
|
||||
}
|
||||
|
||||
fun put(key: String, value: String) {
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.kunzisoft.keepass.database.element
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.database.exception.InvalidKeyFileException
|
||||
import com.kunzisoft.keepass.database.exception.KeyFileEmptyException
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
@@ -118,43 +118,41 @@ abstract class PwDatabase<Group : PwGroup<*, Group, Entry>, Entry : PwEntry<Grou
|
||||
@Throws(InvalidKeyFileException::class, IOException::class)
|
||||
protected fun getFileKey(keyInputStream: InputStream): ByteArray {
|
||||
|
||||
val bos = ByteArrayOutputStream()
|
||||
MemUtil.copyStream(keyInputStream, bos)
|
||||
val keyData = bos.toByteArray()
|
||||
val keyByteArrayOutputStream = ByteArrayOutputStream()
|
||||
MemoryUtil.copyStream(keyInputStream, keyByteArrayOutputStream)
|
||||
//StreamUtils.copy(keyInputStream, keyByteArrayOutputStream);
|
||||
val keyData = keyByteArrayOutputStream.toByteArray()
|
||||
|
||||
val bis = ByteArrayInputStream(keyData)
|
||||
val key = loadXmlKeyFile(bis)
|
||||
val keyByteArrayInputStream = ByteArrayInputStream(keyData)
|
||||
val key = loadXmlKeyFile(keyByteArrayInputStream)
|
||||
if (key != null) {
|
||||
return key
|
||||
}
|
||||
|
||||
val fileSize = keyData.size.toLong()
|
||||
if (fileSize == 0L) {
|
||||
throw KeyFileEmptyException()
|
||||
} else if (fileSize == 32L) {
|
||||
return keyData
|
||||
} else if (fileSize == 64L) {
|
||||
try {
|
||||
when (keyData.size.toLong()) {
|
||||
0L -> throw KeyFileEmptyException()
|
||||
32L -> return keyData
|
||||
64L -> try {
|
||||
return hexStringToByteArray(String(keyData))
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
// Key is not base 64, treat it as binary data
|
||||
}
|
||||
}
|
||||
|
||||
val md: MessageDigest
|
||||
val messageDigest: MessageDigest
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256")
|
||||
messageDigest = MessageDigest.getInstance("SHA-256")
|
||||
} catch (e: NoSuchAlgorithmException) {
|
||||
throw IOException("SHA-256 not supported")
|
||||
}
|
||||
|
||||
try {
|
||||
md.update(keyData)
|
||||
messageDigest.update(keyData)
|
||||
} catch (e: Exception) {
|
||||
println(e.toString())
|
||||
}
|
||||
|
||||
return md.digest()
|
||||
return messageDigest.digest()
|
||||
}
|
||||
|
||||
protected abstract fun loadXmlKeyFile(keyInputStream: InputStream): ByteArray?
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedBinary
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
import java.util.*
|
||||
|
||||
class PwEntryV4 : PwEntry<PwGroupV4, PwEntryV4>, NodeV4Interface {
|
||||
@@ -94,9 +94,9 @@ class PwEntryV4 : PwEntry<PwGroupV4, PwEntryV4>, NodeV4Interface {
|
||||
iconCustom = parcel.readParcelable(PwIconCustom::class.java.classLoader)
|
||||
usageCount = parcel.readLong()
|
||||
locationChanged = parcel.readParcelable(PwDate::class.java.classLoader)
|
||||
customData = MemUtil.readStringParcelableMap(parcel)
|
||||
fields = MemUtil.readStringParcelableMap(parcel, ProtectedString::class.java)
|
||||
// TODO binaries = MemUtil.readStringParcelableMap(parcel, ProtectedBinary.class);
|
||||
customData = MemoryUtil.readStringParcelableMap(parcel)
|
||||
fields = MemoryUtil.readStringParcelableMap(parcel, ProtectedString::class.java)
|
||||
// TODO binaries = MemoryUtil.readStringParcelableMap(parcel, ProtectedBinary.class);
|
||||
foregroundColor = parcel.readString()
|
||||
backgroundColor = parcel.readString()
|
||||
overrideURL = parcel.readString()
|
||||
@@ -112,9 +112,9 @@ class PwEntryV4 : PwEntry<PwGroupV4, PwEntryV4>, NodeV4Interface {
|
||||
dest.writeParcelable(iconCustom, flags)
|
||||
dest.writeLong(usageCount)
|
||||
dest.writeParcelable(locationChanged, flags)
|
||||
MemUtil.writeStringParcelableMap(dest, customData)
|
||||
MemUtil.writeStringParcelableMap(dest, flags, fields)
|
||||
// TODO MemUtil.writeStringParcelableMap(dest, flags, binaries);
|
||||
MemoryUtil.writeStringParcelableMap(dest, customData)
|
||||
MemoryUtil.writeStringParcelableMap(dest, flags, fields)
|
||||
// TODO MemoryUtil.writeStringParcelableMap(dest, flags, binaries);
|
||||
dest.writeString(foregroundColor)
|
||||
dest.writeString(backgroundColor)
|
||||
dest.writeString(overrideURL)
|
||||
|
||||
@@ -66,7 +66,7 @@ class PwGroupV4 : PwGroup<UUID, PwGroupV4, PwEntryV4>, NodeV4Interface {
|
||||
iconCustom = parcel.readParcelable(PwIconCustom::class.java.classLoader)
|
||||
usageCount = parcel.readLong()
|
||||
locationChanged = parcel.readParcelable(PwDate::class.java.classLoader)
|
||||
// TODO customData = MemUtil.readStringParcelableMap(in);
|
||||
// TODO customData = MemoryUtil.readStringParcelableMap(in);
|
||||
notes = parcel.readString()
|
||||
isExpanded = parcel.readByte().toInt() != 0
|
||||
defaultAutoTypeSequence = parcel.readString()
|
||||
@@ -88,7 +88,7 @@ class PwGroupV4 : PwGroup<UUID, PwGroupV4, PwEntryV4>, NodeV4Interface {
|
||||
dest.writeParcelable(iconCustom, flags)
|
||||
dest.writeLong(usageCount)
|
||||
dest.writeParcelable(locationChanged, flags)
|
||||
// TODO MemUtil.writeStringParcelableMap(dest, customData);
|
||||
// TODO MemoryUtil.writeStringParcelableMap(dest, customData);
|
||||
dest.writeString(notes)
|
||||
dest.writeByte((if (isExpanded) 1 else 0).toByte())
|
||||
dest.writeString(defaultAutoTypeSequence)
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.kunzisoft.keepass.stream.HmacBlockInputStream
|
||||
import com.kunzisoft.keepass.stream.LEDataInputStream
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||
import com.kunzisoft.keepass.database.file.KDBX4DateUtil
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
import com.kunzisoft.keepass.utils.Types
|
||||
import org.spongycastle.crypto.StreamCipher
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
@@ -933,7 +933,7 @@ class ImporterV4(private val streamDir: File) : Importer<PwDatabaseV4>() {
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun createProtectedBinaryFromData(protection: Boolean, data: ByteArray): ProtectedBinary {
|
||||
return if (data.size > MemUtil.BUFFER_SIZE_BYTES) {
|
||||
return if (data.size > MemoryUtil.BUFFER_SIZE_BYTES) {
|
||||
val file = File(streamDir, unusedCacheFileName)
|
||||
FileOutputStream(file).use { outputStream -> outputStream.write(data) }
|
||||
ProtectedBinary(protection, file, data.size)
|
||||
@@ -971,7 +971,7 @@ class ImporterV4(private val streamDir: File) : Importer<PwDatabaseV4>() {
|
||||
var data = Base64Coder.decode(base64)
|
||||
|
||||
if (compressed) {
|
||||
data = MemUtil.decompress(data)
|
||||
data = MemoryUtil.decompress(data)
|
||||
}
|
||||
|
||||
return createProtectedBinaryFromData(false, data)
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.kunzisoft.keepass.database.element.PwDatabaseV4
|
||||
import com.kunzisoft.keepass.database.file.PwDbHeaderV4
|
||||
import com.kunzisoft.keepass.stream.ActionReadBytes
|
||||
import com.kunzisoft.keepass.stream.LEDataOutputStream
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import kotlin.experimental.or
|
||||
@@ -56,7 +56,7 @@ class PwDbInnerHeaderOutputV4(private val db: PwDatabaseV4, private val header:
|
||||
los.write(flag.toInt())
|
||||
|
||||
protectedBinary.getData()?.let {
|
||||
MemUtil.readBytes(it, ActionReadBytes { buffer ->
|
||||
MemoryUtil.readBytes(it, ActionReadBytes { buffer ->
|
||||
los.write(buffer)
|
||||
})
|
||||
} ?: throw IOException("Can't write protected binary")
|
||||
|
||||
@@ -39,7 +39,7 @@ import com.kunzisoft.keepass.stream.HashedBlockOutputStream
|
||||
import com.kunzisoft.keepass.stream.HmacBlockOutputStream
|
||||
import com.kunzisoft.keepass.stream.LEDataOutputStream
|
||||
import com.kunzisoft.keepass.database.file.KDBX4DateUtil
|
||||
import com.kunzisoft.keepass.utils.MemUtil
|
||||
import com.kunzisoft.keepass.utils.MemoryUtil
|
||||
import com.kunzisoft.keepass.utils.Types
|
||||
import org.joda.time.DateTime
|
||||
import org.spongycastle.crypto.StreamCipher
|
||||
@@ -423,7 +423,7 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4, outputStream: OutputSt
|
||||
try (InputStream base64InputStream =
|
||||
IOUtil.pipe(inputStream,
|
||||
o -> new Base64OutputStream(o, DEFAULT))) {
|
||||
MemUtil.readBytes(base64InputStream,
|
||||
MemoryUtil.readBytes(base64InputStream,
|
||||
buffer -> xml.text(Arrays.toString(buffer)));
|
||||
}
|
||||
}
|
||||
@@ -448,7 +448,7 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4, outputStream: OutputSt
|
||||
if (mDatabaseV4.compressionAlgorithm === PwCompressionAlgorithm.Gzip) {
|
||||
xml.attribute(null, PwDatabaseV4XML.AttrCompressed, PwDatabaseV4XML.ValTrue)
|
||||
|
||||
val compressData = MemUtil.compress(buffer)
|
||||
val compressData = MemoryUtil.compress(buffer)
|
||||
xml.text(String(Base64Coder.encode(compressData)))
|
||||
|
||||
} else {
|
||||
|
||||
@@ -38,24 +38,26 @@ import java.util.HashMap
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
object MemUtil {
|
||||
object MemoryUtil {
|
||||
|
||||
private val TAG = MemUtil::class.java.name
|
||||
private val TAG = MemoryUtil::class.java.name
|
||||
const val BUFFER_SIZE_BYTES = 3 * 128
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun copyStream(inputStream: InputStream, out: OutputStream) {
|
||||
val buf = ByteArray(BUFFER_SIZE_BYTES)
|
||||
val read: Int
|
||||
val buffer = ByteArray(BUFFER_SIZE_BYTES)
|
||||
try {
|
||||
read = inputStream.read(buf)
|
||||
var read = inputStream.read(buffer)
|
||||
while (read != -1) {
|
||||
out.write(buf, 0, read)
|
||||
out.write(buffer, 0, read)
|
||||
read = inputStream.read(buffer)
|
||||
if (Thread.interrupted()) {
|
||||
throw InterruptedException()
|
||||
}
|
||||
}
|
||||
} catch (error: OutOfMemoryError) {
|
||||
throw IOException(error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
Reference in New Issue
Block a user