diff --git a/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt b/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt index 0d1dad9d..fdefe298 100644 --- a/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt +++ b/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt @@ -56,7 +56,7 @@ internal class MethodResolver(private val classList: List, private va companion object { fun resolveMethod(classNode: ClassNode, signature: Signature): PatchData? { for (method in classNode.methods) { - val (r, sr) = cmp(method, signature, true) + val (r, sr) = cmp(method, signature) if (!r || sr == null) continue return PatchData( classNode, @@ -67,52 +67,55 @@ internal class MethodResolver(private val classList: List, private va return null } - private fun cmp(method: MethodNode, signature: Signature, search: Boolean = false): Pair { - val returns = Type.getReturnType(method.desc).convertObject() - if (signature.returns != returns) { - logger.debug { - """ - Comparing sig ${signature.name}: invalid return type: - expected ${signature.returns}}, - got $returns - """.trimIndent() + private fun cmp(method: MethodNode, signature: Signature): Pair { + signature.returns?.let { _ -> + val methodReturns = Type.getReturnType(method.desc).convertObject() + if (signature.returns != methodReturns) { + logger.debug { + """ + Comparing sig ${signature.name}: invalid return type: + expected ${signature.returns}, + got $methodReturns + """.trimIndent() + } + return@cmp false to null } - return false to null } - if (signature.accessors != method.access) { - logger.debug { - """ - Comparing sig ${signature.name}: invalid accessors: - expected ${signature.accessors}}, - got ${method.access} - """.trimIndent() + signature.accessors?.let { _ -> + if (signature.accessors != method.access) { + logger.debug { + """ + Comparing sig ${signature.name}: invalid accessors: + expected ${signature.accessors}, + got ${method.access} + """.trimIndent() + } + return@cmp false to null } - return false to null } - val parameters = Type.getArgumentTypes(method.desc).convertObjects() - if (!signature.parameters.contentEquals(parameters)) { - logger.debug { - """ - Comparing sig ${signature.name}: invalid parameter types: - expected ${signature.parameters.joinToString()}}, - got ${parameters.joinToString()} - """.trimIndent() + signature.parameters?.let { _ -> + val parameters = Type.getArgumentTypes(method.desc).convertObjects() + if (!signature.parameters.contentEquals(parameters)) { + logger.debug { + """ + Comparing sig ${signature.name}: invalid parameter types: + expected ${signature.parameters.joinToString()}}, + got ${parameters.joinToString()} + """.trimIndent() + } + return@cmp false to null } - return false to null } - if (!search) { - if (signature.opcodes.isEmpty()) { - throw IllegalArgumentException("Opcode list for signature ${signature.name} is empty. This is not allowed for non-search signatures.") - } + signature.opcodes?.let { _ -> val result = method.instructions.scanFor(signature.opcodes) if (!result.found) { logger.debug { "Comparing sig ${signature.name}: invalid opcode pattern" } - return false to null + return@cmp false to null } - return true to result + return@cmp true to result } return true to ScanResult(true) diff --git a/src/main/kotlin/net/revanced/patcher/signature/Signature.kt b/src/main/kotlin/net/revanced/patcher/signature/Signature.kt index 4c364b9c..50f9cf00 100644 --- a/src/main/kotlin/net/revanced/patcher/signature/Signature.kt +++ b/src/main/kotlin/net/revanced/patcher/signature/Signature.kt @@ -9,21 +9,19 @@ import org.objectweb.asm.Type * Do not use the actual method name, instead try to guess what the method name originally was. * If you are unable to guess a method name, doing something like "patch-name-1" is fine too. * For example: "override-codec-1". - * This method name will be used to find the corresponding patch. + * This method name will be mapped to the method matching the signature. * Even though this is technically not needed for the `findParentMethod` method, * it is still recommended giving the method a name, so it can be identified easily. * @param returns The return type/signature of the method. * @param accessors The accessors of the method. * @param parameters The parameter types of the method. * @param opcodes The opcode pattern of the method, used to find the method by pattern scanning. - * ***Only if*** **you are using **`findParentMethod`** are you allowed to specify an empty array.** - * This parameter will be ignored when using the `findParentMethod` method. */ @Suppress("ArrayInDataClass") data class Signature( val name: String, - val returns: Type, - val accessors: Int, - val parameters: Array, - val opcodes: Array + val returns: Type?, + val accessors: Int?, + val parameters: Array?, + val opcodes: Array? ) \ No newline at end of file diff --git a/src/test/kotlin/net/revanced/patcher/PatcherTest.kt b/src/test/kotlin/net/revanced/patcher/PatcherTest.kt index 9eee7020..9cecec5c 100644 --- a/src/test/kotlin/net/revanced/patcher/PatcherTest.kt +++ b/src/test/kotlin/net/revanced/patcher/PatcherTest.kt @@ -9,13 +9,12 @@ import net.revanced.patcher.util.ExtraTypes import net.revanced.patcher.util.TestUtil import net.revanced.patcher.writer.ASMWriter.insertAt import net.revanced.patcher.writer.ASMWriter.setAt -import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.assertDoesNotThrow import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type import org.objectweb.asm.tree.* import java.io.PrintStream import kotlin.test.Test -import kotlin.test.assertEquals internal class PatcherTest { companion object { @@ -149,25 +148,21 @@ internal class PatcherTest { //} @Test() - fun `should raise an exception because opcodes is empty`() { + fun `should not raise an exception if any signature member except the name is missing`() { val sigName = "testMethod" - val e = assertThrows("Should raise an exception because opcodes is empty") { + + assertDoesNotThrow("Should raise an exception because opcodes is empty") { Patcher( PatcherTest::class.java.getResourceAsStream("/test1.jar")!!, arrayOf( Signature( sigName, - Type.VOID_TYPE, - ACC_PUBLIC or ACC_STATIC, - arrayOf(ExtraTypes.ArrayAny), - emptyArray() // this is not allowed for non-search signatures! - ) - ) + null, + null, + null, + null + )) ) } - assertEquals( - "Opcode list for signature $sigName is empty. This is not allowed for non-search signatures.", - e.message - ) } } \ No newline at end of file