diff --git a/presentation/src/main/java/org/cryptomator/presentation/e/c.java b/presentation/src/main/java/org/cryptomator/presentation/e/c.java new file mode 100644 index 00000000..8cba6ec2 --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/e/c.java @@ -0,0 +1,57 @@ +package org.cryptomator.presentation.e; + +import java.io.Serializable; +import java.util.Set; + +/** + * This file is the obfuscated AutoUploadFilesStore of Cryptomator in version 1.5.10 + * and is used to recover it in version 1.5.11 and 1.5.11-beta2 + * + * TODO Delete as soon as possible + * + * See more information: https://github.com/cryptomator/android/issues/250 + */ + +public final class c implements Serializable { + + public static final a Qb = new a(); + private static final long serialVersionUID = -2190476748996271234L; + + private final Set vlb; + + public c(Set paramSet) { + this.vlb = paramSet; + } + + public boolean equals(Object paramObject) { + if (this != paramObject) { + if (paramObject instanceof c) { + Object paramObject2 = ((c)paramObject).vlb; + return (this.vlb == null) ? ((paramObject2 == null)) : this.vlb.equals(paramObject2); + } + return false; + } + return true; + } + + public int hashCode() { + Set set = this.vlb; + return (set != null) ? set.hashCode() : 0; + } + + public final Set mE() { + return this.vlb; + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("AutoUploadFilesStore(uris="); + stringBuilder.append(this.vlb); + stringBuilder.append(")"); + return stringBuilder.toString(); + } + + public static final class a { + private a() {} + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/i/a.java b/presentation/src/main/java/org/cryptomator/presentation/i/a.java new file mode 100644 index 00000000..9444f86d --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/i/a.java @@ -0,0 +1,57 @@ +package org.cryptomator.presentation.i; + +import java.io.Serializable; +import java.util.Set; + +/** + * This file is the obfuscated AutoUploadFilesStore of Cryptomator in version 1.5.11-beta1 + * and is used to recover it in version 1.5.11-beta2 + * + * TODO Delete as soon as possible + * + * See more information: https://github.com/cryptomator/android/issues/250 + */ + +public final class a implements Serializable { + + private static final long serialVersionUID = 5147365921479820025L; + private final Set b; + + public a(Set paramSet) { + this.b = paramSet; + } + + public final Set b() { + return this.b; + } + + public boolean equals(Object paramObject) { + if (this != paramObject) { + if (paramObject instanceof a) { + Object paramObject2 = ((a)paramObject).b; + return (this.b == null) ? ((paramObject2 == null)) : this.b.equals(paramObject2); + } + return false; + } + return true; + } + + public int hashCode() { + int bool; + Set set = this.b; + if (set != null) { + bool = set.hashCode(); + } else { + bool = 0; + } + return bool; + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("AutoUploadFilesStore(uris="); + stringBuilder.append(this.b); + stringBuilder.append(")"); + return stringBuilder.toString(); + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt b/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt index 402b1c95..a0a24cfa 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt @@ -125,7 +125,9 @@ class FileUtil @Inject constructor(private val context: Context, private val mim fun getImagePreviewFiles(path: String): ImagePreviewFilesStore { try { - ObjectInputStream(FileInputStream(path)).use { objectInputStream -> return objectInputStream.readObject() as ImagePreviewFilesStore } + ObjectInputStream(FileInputStream(path)).use { objectInputStream -> + return objectInputStream.readObject() as ImagePreviewFilesStore + } } catch (e: ClassNotFoundException) { Timber // .tag("FileUtil") // @@ -139,40 +141,39 @@ class FileUtil @Inject constructor(private val context: Context, private val mim } } - fun addImageToAutoUploads(path: String) { - val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES) - val paths = getAutoUploadFilesStore(file).uris + path - addImageToAutoUploads(paths) + fun addImageToAutoUploads(path: String): AutoUploadFilesStore { + val paths = getAutoUploadFilesStore().uris + path + return addImageToAutoUploads(paths) } - private fun addImageToAutoUploads(paths: Set) { - addImageToAutoUploads(AutoUploadFilesStore(paths)) + private fun addImageToAutoUploads(paths: Set): AutoUploadFilesStore { + return addImageToAutoUploads(AutoUploadFilesStore(paths)) } @Synchronized - private fun addImageToAutoUploads(autoUploadFilesStore: AutoUploadFilesStore) { + private fun addImageToAutoUploads(autoUploadFilesStore: AutoUploadFilesStore): AutoUploadFilesStore { try { decryptedFileStorage.mkdir() + val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES) - val out: ObjectOutput = ObjectOutputStream(FileOutputStream(file.path)) - out.writeObject(autoUploadFilesStore) - out.close() + + ObjectOutputStream(FileOutputStream(file.path)).use { objectOutputStream -> + objectOutputStream.writeObject(autoUploadFilesStore) + objectOutputStream.close() + } + + return autoUploadFilesStore } catch (e: IOException) { Timber // .tag("FileUtil") // .e(e, "Failed to store image preview file list for PreviewActivity") + throw FatalBackendException(e) } } - @get:Throws(FatalBackendException::class) - val autoUploadFilesStore: AutoUploadFilesStore - get() { - val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES) - return getAutoUploadFilesStore(file) - } - @Synchronized - private fun getAutoUploadFilesStore(file: File): AutoUploadFilesStore { + fun getAutoUploadFilesStore(): AutoUploadFilesStore { + val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES) if (!file.exists()) { return AutoUploadFilesStore(HashSet()) } @@ -183,20 +184,9 @@ class FileUtil @Inject constructor(private val context: Context, private val mim return autoUploadFilesStore } } catch (e: InvalidClassException) { - Timber // - .tag("FileUtil") // - .e(e, "This is a bug in Cryptomator version 1.4.1, only fix is to delete the AutoUploadFilesStore but no image inside so no problem") - if (!file.delete()) { - Timber // - .tag("FileUtil") // - .e("Failed to delete AutoUploadFilesStore") - } - throw FatalBackendException(e) - } catch (e: ClassNotFoundException) { - Timber // - .tag("FileUtil") // - .e(e, "Failed to read image preview file from list for PreviewActivity") - throw FatalBackendException(e) + return tryRecoverAutoUploadFilesStoreDueToFileObfuscation(file) + } catch (e: ClassCastException) { + return tryRecoverAutoUploadFilesStoreDueToFileObfuscation(file) } catch (e: IOException) { Timber .tag("FileUtil") @@ -205,20 +195,47 @@ class FileUtil @Inject constructor(private val context: Context, private val mim } } + /** + * This method tries to recover the AutoUploadFilesStore which was obfuscated in version 1.5.10 and 1.5.11-beta1, each differently + */ + private fun tryRecoverAutoUploadFilesStoreDueToFileObfuscation(file: File): AutoUploadFilesStore { + Timber.tag("FileUtil").i("Try to recover AutoUploadFilesStore using class c or a") + try { + ObjectInputStream(FileInputStream(file)).use { objectInputStream -> + val uploadPaths = when (val obj = objectInputStream.readObject()) { + is org.cryptomator.presentation.e.c -> obj.mE() // version 1.5.10 + is org.cryptomator.presentation.i.a -> obj.b() // version 1.5.11-beta1 + else -> null + } + when { + uploadPaths != null -> { + Timber.tag("FileUtil").i("Nailed it! Successfully recovered AutoUploadFilesStore!") + file.delete() + return AutoUploadFilesStore(uploadPaths) + } + else -> throw FatalBackendException("Failed to recover AutoUploadFilesStore") + } + } + } catch (e: Exception) { + throw FatalBackendException("Failed to recover AutoUploadFilesStore", e) + } + } + @Synchronized - fun removeImagesFromAutoUploads(names: Set) { - val autoUploadFilesStore = autoUploadFilesStore + fun removeImagesFromAutoUploads(names: Set): AutoUploadFilesStore { + val autoUploadFilesStore = getAutoUploadFilesStore() var paths = autoUploadFilesStore.uris if (autoUploadFilesStore.uris.isEmpty()) { - return + return autoUploadFilesStore } val dirPath = File(autoUploadFilesStore.uris.iterator().next()).parent names.forEach { name -> paths = paths.minus(String.format("%s/%s", dirPath, name)) } - addImageToAutoUploads(paths) + + return addImageToAutoUploads(paths) } class FileInfo(val name: String, mimeTypes: MimeTypes) {