mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2024-11-13 02:14:27 +01:00
fix: Classes not being written properly because of array shifting
We now use a MutableList to replace it at the proper index, and use a ListBackedSet, so we don't copy List's to Set's for no reason. This was a very bad issue. The array was shifted every time we removed the original class, the fact we even got a "working" dex file surprises me. Thankfully, this issue is now solved, and we lived happily after.
This commit is contained in:
parent
433914feda
commit
147195647c
4 changed files with 21 additions and 12 deletions
|
@ -1,11 +1,11 @@
|
|||
package app.revanced.patcher
|
||||
|
||||
import app.revanced.patcher.cache.Cache
|
||||
import app.revanced.patcher.extensions.replace
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.signature.resolver.SignatureResolver
|
||||
import app.revanced.patcher.signature.MethodSignature
|
||||
import app.revanced.patcher.util.ListBackedSet
|
||||
import lanchon.multidexlib2.BasicDexFileNamer
|
||||
import lanchon.multidexlib2.DexIO
|
||||
import lanchon.multidexlib2.MultiDexIO
|
||||
|
@ -33,7 +33,7 @@ class Patcher(
|
|||
init {
|
||||
val dexFile = MultiDexIO.readDexFile(true, input, NAMER, null, null)
|
||||
opcodes = dexFile.opcodes
|
||||
cache = Cache(dexFile.classes.toMutableSet(), SignatureResolver(dexFile.classes, signatures).resolve())
|
||||
cache = Cache(dexFile.classes.toMutableList(), SignatureResolver(dexFile.classes, signatures).resolve())
|
||||
}
|
||||
/**
|
||||
* Add additional dex file container to the patcher.
|
||||
|
@ -62,13 +62,13 @@ class Patcher(
|
|||
// this is a slow workaround for now
|
||||
cache.methodMap.values.forEach {
|
||||
if (it.definingClassProxy.proxyUsed) {
|
||||
cache.classes.replace(it.definingClassProxy.originalIndex, it.definingClassProxy.mutatedClass)
|
||||
cache.classes[it.definingClassProxy.originalIndex] = it.definingClassProxy.mutatedClass
|
||||
}
|
||||
}
|
||||
cache.classProxy.filter { it.proxyUsed }.forEach { proxy ->
|
||||
cache.classes.replace(proxy.originalIndex, proxy.mutatedClass)
|
||||
cache.classes[proxy.originalIndex] = proxy.mutatedClass
|
||||
}
|
||||
return cache.classes
|
||||
return ListBackedSet(cache.classes)
|
||||
}
|
||||
|
||||
override fun getOpcodes(): Opcodes {
|
||||
|
|
|
@ -5,7 +5,7 @@ import app.revanced.patcher.signature.SignatureResolverResult
|
|||
import org.jf.dexlib2.iface.ClassDef
|
||||
|
||||
class Cache(
|
||||
internal val classes: MutableSet<ClassDef>,
|
||||
internal val classes: MutableList<ClassDef>,
|
||||
val methodMap: MethodMap
|
||||
) {
|
||||
// TODO: currently we create ClassProxies at multiple places, which is why we could have merge conflicts
|
||||
|
|
|
@ -3,7 +3,6 @@ package app.revanced.patcher.extensions
|
|||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.builder.BuilderInstruction
|
||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
||||
import org.jf.dexlib2.iface.ClassDef
|
||||
|
||||
infix fun AccessFlags.or(other: AccessFlags) = this.value or other.value
|
||||
|
||||
|
@ -12,8 +11,3 @@ fun MutableMethodImplementation.addInstructions(index: Int, instructions: List<B
|
|||
this.addInstruction(index, instructions[i])
|
||||
}
|
||||
}
|
||||
|
||||
internal fun MutableSet<ClassDef>.replace(originalIndex: Int, mutatedClass: ClassDef) {
|
||||
this.remove(this.elementAt(originalIndex))
|
||||
this.add(mutatedClass)
|
||||
}
|
||||
|
|
15
src/main/kotlin/app/revanced/patcher/util/ListBackedSet.kt
Normal file
15
src/main/kotlin/app/revanced/patcher/util/ListBackedSet.kt
Normal file
|
@ -0,0 +1,15 @@
|
|||
package app.revanced.patcher.util
|
||||
|
||||
class ListBackedSet<E>(private val list: MutableList<E>) : MutableSet<E> {
|
||||
override val size get() = list.size
|
||||
override fun add(element: E) = list.add(element)
|
||||
override fun addAll(elements: Collection<E>) = list.addAll(elements)
|
||||
override fun clear() = list.clear()
|
||||
override fun iterator() = list.listIterator()
|
||||
override fun remove(element: E) = list.remove(element)
|
||||
override fun removeAll(elements: Collection<E>) = list.removeAll(elements)
|
||||
override fun retainAll(elements: Collection<E>) = list.retainAll(elements)
|
||||
override fun contains(element: E) = list.contains(element)
|
||||
override fun containsAll(elements: Collection<E>) = list.containsAll(elements)
|
||||
override fun isEmpty() = list.isEmpty()
|
||||
}
|
Loading…
Reference in a new issue