#250 Recover AutoUploadFilesStore due to class obfuscation
AutoUploadFilesStore, which handles serializing the paths marked to upload, is obfuscated in version 1.5.10 and 1.5.11-beta1, each differently. This causes deserialisation to fail in 1.5.11-beta1 which is now fixed for the next version.
This commit is contained in:
parent
8ae7d06c49
commit
5f428b5963
@ -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<String> vlb;
|
||||||
|
|
||||||
|
public c(Set<String> 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<String> set = this.vlb;
|
||||||
|
return (set != null) ? set.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Set<String> 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() {}
|
||||||
|
}
|
||||||
|
}
|
@ -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<String> b;
|
||||||
|
|
||||||
|
public a(Set<String> paramSet) {
|
||||||
|
this.b = paramSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Set<String> 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<String> 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();
|
||||||
|
}
|
||||||
|
}
|
@ -125,7 +125,9 @@ class FileUtil @Inject constructor(private val context: Context, private val mim
|
|||||||
|
|
||||||
fun getImagePreviewFiles(path: String): ImagePreviewFilesStore {
|
fun getImagePreviewFiles(path: String): ImagePreviewFilesStore {
|
||||||
try {
|
try {
|
||||||
ObjectInputStream(FileInputStream(path)).use { objectInputStream -> return objectInputStream.readObject() as ImagePreviewFilesStore }
|
ObjectInputStream(FileInputStream(path)).use { objectInputStream ->
|
||||||
|
return objectInputStream.readObject() as ImagePreviewFilesStore
|
||||||
|
}
|
||||||
} catch (e: ClassNotFoundException) {
|
} catch (e: ClassNotFoundException) {
|
||||||
Timber //
|
Timber //
|
||||||
.tag("FileUtil") //
|
.tag("FileUtil") //
|
||||||
@ -139,40 +141,39 @@ class FileUtil @Inject constructor(private val context: Context, private val mim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addImageToAutoUploads(path: String) {
|
fun addImageToAutoUploads(path: String): AutoUploadFilesStore {
|
||||||
val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES)
|
val paths = getAutoUploadFilesStore().uris + path
|
||||||
val paths = getAutoUploadFilesStore(file).uris + path
|
return addImageToAutoUploads(paths)
|
||||||
addImageToAutoUploads(paths)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addImageToAutoUploads(paths: Set<String>) {
|
private fun addImageToAutoUploads(paths: Set<String>): AutoUploadFilesStore {
|
||||||
addImageToAutoUploads(AutoUploadFilesStore(paths))
|
return addImageToAutoUploads(AutoUploadFilesStore(paths))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun addImageToAutoUploads(autoUploadFilesStore: AutoUploadFilesStore) {
|
private fun addImageToAutoUploads(autoUploadFilesStore: AutoUploadFilesStore): AutoUploadFilesStore {
|
||||||
try {
|
try {
|
||||||
decryptedFileStorage.mkdir()
|
decryptedFileStorage.mkdir()
|
||||||
|
|
||||||
val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES)
|
val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES)
|
||||||
val out: ObjectOutput = ObjectOutputStream(FileOutputStream(file.path))
|
|
||||||
out.writeObject(autoUploadFilesStore)
|
ObjectOutputStream(FileOutputStream(file.path)).use { objectOutputStream ->
|
||||||
out.close()
|
objectOutputStream.writeObject(autoUploadFilesStore)
|
||||||
|
objectOutputStream.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoUploadFilesStore
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Timber //
|
Timber //
|
||||||
.tag("FileUtil") //
|
.tag("FileUtil") //
|
||||||
.e(e, "Failed to store image preview file list for PreviewActivity")
|
.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
|
@Synchronized
|
||||||
private fun getAutoUploadFilesStore(file: File): AutoUploadFilesStore {
|
fun getAutoUploadFilesStore(): AutoUploadFilesStore {
|
||||||
|
val file = File(decryptedFileStorage, AUTO_UPLOAD_IMAGE__FILE_NAMES)
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
return AutoUploadFilesStore(HashSet())
|
return AutoUploadFilesStore(HashSet())
|
||||||
}
|
}
|
||||||
@ -183,20 +184,9 @@ class FileUtil @Inject constructor(private val context: Context, private val mim
|
|||||||
return autoUploadFilesStore
|
return autoUploadFilesStore
|
||||||
}
|
}
|
||||||
} catch (e: InvalidClassException) {
|
} catch (e: InvalidClassException) {
|
||||||
Timber //
|
return tryRecoverAutoUploadFilesStoreDueToFileObfuscation(file)
|
||||||
.tag("FileUtil") //
|
} catch (e: ClassCastException) {
|
||||||
.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")
|
return tryRecoverAutoUploadFilesStoreDueToFileObfuscation(file)
|
||||||
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)
|
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Timber
|
Timber
|
||||||
.tag("FileUtil")
|
.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
|
@Synchronized
|
||||||
fun removeImagesFromAutoUploads(names: Set<String>) {
|
fun removeImagesFromAutoUploads(names: Set<String>): AutoUploadFilesStore {
|
||||||
val autoUploadFilesStore = autoUploadFilesStore
|
val autoUploadFilesStore = getAutoUploadFilesStore()
|
||||||
var paths = autoUploadFilesStore.uris
|
var paths = autoUploadFilesStore.uris
|
||||||
|
|
||||||
if (autoUploadFilesStore.uris.isEmpty()) {
|
if (autoUploadFilesStore.uris.isEmpty()) {
|
||||||
return
|
return autoUploadFilesStore
|
||||||
}
|
}
|
||||||
|
|
||||||
val dirPath = File(autoUploadFilesStore.uris.iterator().next()).parent
|
val dirPath = File(autoUploadFilesStore.uris.iterator().next()).parent
|
||||||
names.forEach { name ->
|
names.forEach { name ->
|
||||||
paths = paths.minus(String.format("%s/%s", dirPath, name))
|
paths = paths.minus(String.format("%s/%s", dirPath, name))
|
||||||
}
|
}
|
||||||
addImageToAutoUploads(paths)
|
|
||||||
|
return addImageToAutoUploads(paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileInfo(val name: String, mimeTypes: MimeTypes) {
|
class FileInfo(val name: String, mimeTypes: MimeTypes) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user