mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-04-03 12:57:36 +03:00
fix: Date parser #1933
This commit is contained in:
parent
e780f8a3f0
commit
724698fc51
4 changed files with 44 additions and 28 deletions
|
@ -192,7 +192,7 @@ object AutofillHelper {
|
||||||
} else {
|
} else {
|
||||||
datasetBuilder.addValueToDatasetBuilder(
|
datasetBuilder.addValueToDatasetBuilder(
|
||||||
it,
|
it,
|
||||||
AutofillValue.forDate(entryInfo.expiryTime.toJavaMilliseconds())
|
AutofillValue.forDate(entryInfo.expiryTime.toMilliseconds())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.element
|
||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import android.util.Log
|
||||||
import com.kunzisoft.keepass.utils.readEnum
|
import com.kunzisoft.keepass.utils.readEnum
|
||||||
import com.kunzisoft.keepass.utils.readSerializableCompat
|
import com.kunzisoft.keepass.utils.readSerializableCompat
|
||||||
import com.kunzisoft.keepass.utils.writeEnum
|
import com.kunzisoft.keepass.utils.writeEnum
|
||||||
|
@ -60,11 +61,11 @@ class DateInstant : Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parse(value: String, type: Type): Instant {
|
private fun parse(value: String, type: Type): Instant {
|
||||||
return when (type) {
|
return Instant(when (type) {
|
||||||
Type.DATE -> Instant(dateFormat.parseDateTime(value) ?: DateTime())
|
Type.DATE_TIME -> dateTimeFormat.parseDateTime(value) ?: DateTime()
|
||||||
Type.TIME -> Instant(timeFormat.parseDateTime(value) ?: DateTime())
|
Type.DATE -> dateFormat.parseDateTime(value) ?: DateTime()
|
||||||
else -> Instant(dateTimeFormat.parseDateTime(value) ?: DateTime())
|
Type.TIME -> timeFormat.parseDateTime(value) ?: DateTime()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(string: String, type: Type = Type.DATE_TIME) {
|
constructor(string: String, type: Type = Type.DATE_TIME) {
|
||||||
|
@ -175,20 +176,14 @@ class DateInstant : Parcelable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toDotNetSeconds(): Long {
|
/**
|
||||||
val duration = Duration(JAVA_EPOCH_DATE_TIME, mInstant)
|
* Returns:
|
||||||
val seconds = duration.millis / 1000L
|
* the number of milliseconds since 1970-01-01T00:00:00Z
|
||||||
return seconds + EPOCH_OFFSET
|
*/
|
||||||
}
|
fun toMilliseconds(): Long {
|
||||||
|
|
||||||
fun toJavaMilliseconds(): Long {
|
|
||||||
return mInstant.millis
|
return mInstant.millis
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toDateTimeSecondsFormat(): String {
|
|
||||||
return dateTimeSecondsFormat.print(mInstant)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
Type.DATE -> dateFormat.print(mInstant)
|
Type.DATE -> dateFormat.print(mInstant)
|
||||||
|
@ -239,6 +234,8 @@ class DateInstant : Parcelable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
private val TAG = DateInstant::class.java.name
|
||||||
|
|
||||||
private val DOT_NET_EPOCH_DATE_TIME = DateTime(1, 1, 1, 0, 0, 0, DateTimeZone.UTC)
|
private val DOT_NET_EPOCH_DATE_TIME = DateTime(1, 1, 1, 0, 0, 0, DateTimeZone.UTC)
|
||||||
private val JAVA_EPOCH_DATE_TIME = DateTime(1970, 1, 1, 0, 0, 0, DateTimeZone.UTC)
|
private val JAVA_EPOCH_DATE_TIME = DateTime(1970, 1, 1, 0, 0, 0, DateTimeZone.UTC)
|
||||||
private val EPOCH_OFFSET = (JAVA_EPOCH_DATE_TIME.millis - DOT_NET_EPOCH_DATE_TIME.millis) / 1000L
|
private val EPOCH_OFFSET = (JAVA_EPOCH_DATE_TIME.millis - DOT_NET_EPOCH_DATE_TIME.millis) / 1000L
|
||||||
|
@ -252,27 +249,42 @@ class DateInstant : Parcelable {
|
||||||
val IN_ONE_HOUR_TIME = DateInstant(
|
val IN_ONE_HOUR_TIME = DateInstant(
|
||||||
Instant.now().plus(Duration.standardHours(1)), Type.TIME)
|
Instant.now().plus(Duration.standardHours(1)), Type.TIME)
|
||||||
|
|
||||||
val dateTimeSecondsFormat: DateTimeFormatter =
|
private val ISO8601Format: DateTimeFormatter =
|
||||||
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||||
.withZoneUTC()
|
.withZoneUTC()
|
||||||
var dateTimeFormat: DateTimeFormatter =
|
private var dateTimeFormat: DateTimeFormatter =
|
||||||
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm'Z'")
|
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm'Z'")
|
||||||
.withZoneUTC()
|
.withZoneUTC()
|
||||||
var dateFormat: DateTimeFormatter =
|
private var dateFormat: DateTimeFormatter =
|
||||||
DateTimeFormat.forPattern("yyyy-MM-dd'Z'")
|
DateTimeFormat.forPattern("yyyy-MM-dd'Z'")
|
||||||
.withZoneUTC()
|
.withZoneUTC()
|
||||||
var timeFormat: DateTimeFormatter =
|
private var timeFormat: DateTimeFormatter =
|
||||||
DateTimeFormat.forPattern("HH:mm'Z'")
|
DateTimeFormat.forPattern("HH:mm'Z'")
|
||||||
.withZoneUTC()
|
.withZoneUTC()
|
||||||
|
|
||||||
fun fromDotNetSeconds(seconds: Long): DateInstant {
|
fun Long.fromDotNetSeconds(): DateInstant {
|
||||||
val dt = DOT_NET_EPOCH_DATE_TIME.plus(seconds * 1000L)
|
val dt = DOT_NET_EPOCH_DATE_TIME.plus(this * 1000L)
|
||||||
// Switch corrupted dates to a more recent date that won't cause issues on the client
|
// Switch corrupted dates to a more recent date that won't cause issues on the client
|
||||||
return DateInstant((if (dt.isBefore(JAVA_EPOCH_DATE_TIME)) { JAVA_EPOCH_DATE_TIME } else dt).toInstant())
|
return DateInstant((if (dt.isBefore(JAVA_EPOCH_DATE_TIME)) { JAVA_EPOCH_DATE_TIME } else dt).toInstant())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fromDateTimeSecondsFormat(value: String): DateInstant {
|
fun DateInstant.toDotNetSeconds(): Long {
|
||||||
return DateInstant(dateTimeSecondsFormat.parseDateTime(value).toInstant())
|
val duration = Duration(JAVA_EPOCH_DATE_TIME, mInstant)
|
||||||
|
val seconds = duration.millis / 1000L
|
||||||
|
return seconds + EPOCH_OFFSET
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.fromISO8601Format(): DateInstant {
|
||||||
|
return DateInstant(try {
|
||||||
|
ISO8601Format.parseDateTime(this).toInstant()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Unable to parse date time $this", e)
|
||||||
|
Instant.now()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DateInstant.toISO8601Format(): String {
|
||||||
|
return ISO8601Format.print(this.instant)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
|
|
|
@ -26,6 +26,8 @@ import com.kunzisoft.keepass.database.crypto.CipherEngine
|
||||||
import com.kunzisoft.keepass.database.crypto.CrsAlgorithm
|
import com.kunzisoft.keepass.database.crypto.CrsAlgorithm
|
||||||
import com.kunzisoft.keepass.database.crypto.HmacBlock
|
import com.kunzisoft.keepass.database.crypto.HmacBlock
|
||||||
import com.kunzisoft.keepass.database.element.*
|
import com.kunzisoft.keepass.database.element.*
|
||||||
|
import com.kunzisoft.keepass.database.element.DateInstant.Companion.fromDotNetSeconds
|
||||||
|
import com.kunzisoft.keepass.database.element.DateInstant.Companion.fromISO8601Format
|
||||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||||
import com.kunzisoft.keepass.database.element.binary.BinaryData.Companion.BASE64_FLAG
|
import com.kunzisoft.keepass.database.element.binary.BinaryData.Companion.BASE64_FLAG
|
||||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||||
|
@ -829,7 +831,7 @@ class DatabaseInputKDBX(database: DatabaseKDBX)
|
||||||
var utcDate = DateInstant()
|
var utcDate = DateInstant()
|
||||||
if (mDatabase.kdbxVersion.isBefore(FILE_VERSION_40)) {
|
if (mDatabase.kdbxVersion.isBefore(FILE_VERSION_40)) {
|
||||||
try {
|
try {
|
||||||
utcDate = DateInstant.fromDateTimeSecondsFormat(sDate)
|
utcDate = sDate.fromISO8601Format()
|
||||||
} catch (e: ParseException) {
|
} catch (e: ParseException) {
|
||||||
// Catch with null test below
|
// Catch with null test below
|
||||||
}
|
}
|
||||||
|
@ -841,7 +843,7 @@ class DatabaseInputKDBX(database: DatabaseKDBX)
|
||||||
buf = buf8
|
buf = buf8
|
||||||
}
|
}
|
||||||
val seconds = bytes64ToLong(buf)
|
val seconds = bytes64ToLong(buf)
|
||||||
utcDate = DateInstant.fromDotNetSeconds(seconds)
|
utcDate = seconds.fromDotNetSeconds()
|
||||||
}
|
}
|
||||||
return utcDate
|
return utcDate
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ import com.kunzisoft.encrypt.StreamCipher
|
||||||
import com.kunzisoft.keepass.database.crypto.CrsAlgorithm
|
import com.kunzisoft.keepass.database.crypto.CrsAlgorithm
|
||||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfFactory
|
import com.kunzisoft.keepass.database.crypto.kdf.KdfFactory
|
||||||
import com.kunzisoft.keepass.database.element.*
|
import com.kunzisoft.keepass.database.element.*
|
||||||
|
import com.kunzisoft.keepass.database.element.DateInstant.Companion.toDotNetSeconds
|
||||||
|
import com.kunzisoft.keepass.database.element.DateInstant.Companion.toISO8601Format
|
||||||
import com.kunzisoft.keepass.database.element.binary.BinaryData.Companion.BASE64_FLAG
|
import com.kunzisoft.keepass.database.element.binary.BinaryData.Companion.BASE64_FLAG
|
||||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
||||||
|
@ -412,7 +414,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX)
|
||||||
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
||||||
private fun writeDateInstant(name: String, date: DateInstant) {
|
private fun writeDateInstant(name: String, date: DateInstant) {
|
||||||
if (header!!.version.isBefore(FILE_VERSION_40)) {
|
if (header!!.version.isBefore(FILE_VERSION_40)) {
|
||||||
writeString(name, date.toDateTimeSecondsFormat())
|
writeString(name, date.toISO8601Format())
|
||||||
} else {
|
} else {
|
||||||
writeString(name, String(
|
writeString(name, String(
|
||||||
Base64.encode(
|
Base64.encode(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue