Compare commits

...

17 Commits

Author SHA1 Message Date
semantic-release-bot
5e681ed381 chore(release): 11.0.2-dev.2 [skip ci]
## [11.0.2-dev.2](https://github.com/revanced/revanced-patcher/compare/v11.0.2-dev.1...v11.0.2-dev.2) (2023-06-18)

### Bug Fixes

* use `versionCode` if `versionName` is unavailable ([6e1b647](6e1b6479b6))
2023-06-18 14:41:34 +00:00
oSumAtrIX
6e1b6479b6 fix: use versionCode if versionName is unavailable 2023-06-18 16:39:49 +02:00
semantic-release-bot
f3c9e28a62 chore(release): 11.0.2-dev.1 [skip ci]
## [11.0.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v11.0.1...v11.0.2-dev.1) (2023-06-14)

### Bug Fixes

* catch exceptions from closing patches ([d5d6f85](d5d6f85084))
* only close succeeded patches ([b8151eb](b8151ebccb))
2023-06-14 00:16:26 +00:00
oSumAtrIX
d5d6f85084 fix: catch exceptions from closing patches 2023-06-14 02:14:37 +02:00
oSumAtrIX
b8151ebccb fix: only close succeeded patches 2023-06-14 01:43:19 +02:00
semantic-release-bot
5650e34432 chore(release): 11.0.1 [skip ci]
## [11.0.1](https://github.com/revanced/revanced-patcher/compare/v11.0.0...v11.0.1) (2023-06-12)

### Bug Fixes

* revert using `OutputStream.nullOutputStream` ([f02a426](f02a42610b))
2023-06-12 03:36:10 +00:00
oSumAtrIX
c893d16d52 chore: merge branch dev to main (#190) 2023-06-12 05:34:23 +02:00
semantic-release-bot
34f08bf206 chore(release): 11.0.1-dev.1 [skip ci]
## [11.0.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v11.0.0...v11.0.1-dev.1) (2023-06-12)

### Bug Fixes

* revert using `OutputStream.nullOutputStream` ([f02a426](f02a42610b))
2023-06-12 03:33:53 +00:00
oSumAtrIX
f02a42610b fix: revert using OutputStream.nullOutputStream
Older Android versions don't support this API
2023-06-12 05:32:13 +02:00
oSumAtrIX
c95e6fa92f ci: add cache step 2023-06-12 02:55:09 +02:00
oSumAtrIX
fd738e723b ci: build before running semantic-release 2023-06-12 01:52:52 +02:00
oSumAtrIX
b1d1956323 ci: remove unnecessary steps 2023-06-12 01:47:26 +02:00
semantic-release-bot
725a8012ac chore(release): 11.0.0 [skip ci]
# [11.0.0](https://github.com/revanced/revanced-patcher/compare/v10.0.0...v11.0.0) (2023-06-10)

### Bug Fixes

* add imports to fix failing tests ([43d6868](43d6868d1f))

* refactor!: move extension functions to their corresponding classes ([a12fe7d](a12fe7dd9e))
* refactor!: use proper extension function names ([efdd01a](efdd01a988))
* fix!: implement extension functions consistently ([aacf900](aacf900764))

### BREAKING CHANGES

* This changes the import paths for extension functions.
* This changes the names of extension functions
* This changes the name of functions
2023-06-10 23:11:52 +00:00
oSumAtrIX
bb9a73e53b chore: merge branch dev to main (#187) 2023-06-11 01:10:59 +02:00
semantic-release-bot
ef2de35a74 chore(release): 11.0.0-dev.2 [skip ci]
# [11.0.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v11.0.0-dev.1...v11.0.0-dev.2) (2023-06-09)

### Bug Fixes

* add imports to fix failing tests ([43d6868](43d6868d1f))
2023-06-09 23:56:16 +00:00
oSumAtrIX
2a453d51a8 refactor: rename helper methods for tests 2023-06-10 01:55:05 +02:00
oSumAtrIX
43d6868d1f fix: add imports to fix failing tests 2023-06-10 01:43:09 +02:00
6 changed files with 144 additions and 60 deletions

View File

@@ -23,17 +23,20 @@ jobs:
# https://github.com/cycjimmy/semantic-release-action#private-packages # https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
- name: Setup JDK - name: Cache
uses: actions/setup-java@v3 uses: actions/cache@v3
with: with:
java-version: '17' path: |
distribution: 'zulu' ${{ runner.home }}/.gradle/caches
cache: gradle ${{ runner.home }}/.gradle/wrapper
- name: Setup Node.js .gradle
uses: actions/setup-node@v3 build
with: node_modules
node-version: "18" key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
cache: 'npm' - name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew clean --no-daemon
- name: Setup semantic-release - name: Setup semantic-release
run: npm install run: npm install
- name: Release - name: Release

View File

@@ -1,3 +1,58 @@
## [11.0.2-dev.2](https://github.com/revanced/revanced-patcher/compare/v11.0.2-dev.1...v11.0.2-dev.2) (2023-06-18)
### Bug Fixes
* use `versionCode` if `versionName` is unavailable ([6e1b647](https://github.com/revanced/revanced-patcher/commit/6e1b6479b677657c226693e9cc6b63f4ef2ee060))
## [11.0.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v11.0.1...v11.0.2-dev.1) (2023-06-14)
### Bug Fixes
* catch exceptions from closing patches ([d5d6f85](https://github.com/revanced/revanced-patcher/commit/d5d6f85084c03ed9c776632823ca12394a716167))
* only close succeeded patches ([b8151eb](https://github.com/revanced/revanced-patcher/commit/b8151ebccb5b27dd9e06fa63235cf9baeef1c0ee))
## [11.0.1](https://github.com/revanced/revanced-patcher/compare/v11.0.0...v11.0.1) (2023-06-12)
### Bug Fixes
* revert using `OutputStream.nullOutputStream` ([f02a426](https://github.com/revanced/revanced-patcher/commit/f02a42610b7698fc8cc6bc5183c9ccba2ed96cda))
## [11.0.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v11.0.0...v11.0.1-dev.1) (2023-06-12)
### Bug Fixes
* revert using `OutputStream.nullOutputStream` ([f02a426](https://github.com/revanced/revanced-patcher/commit/f02a42610b7698fc8cc6bc5183c9ccba2ed96cda))
# [11.0.0](https://github.com/revanced/revanced-patcher/compare/v10.0.0...v11.0.0) (2023-06-10)
### Bug Fixes
* add imports to fix failing tests ([43d6868](https://github.com/revanced/revanced-patcher/commit/43d6868d1f59922f9812f3e4a2a890f3b331def6))
* refactor!: move extension functions to their corresponding classes ([a12fe7d](https://github.com/revanced/revanced-patcher/commit/a12fe7dd9e976c38a0a82fe35e6650f58f815de4))
* refactor!: use proper extension function names ([efdd01a](https://github.com/revanced/revanced-patcher/commit/efdd01a9886b6f06af213731824621964367b2a3))
* fix!: implement extension functions consistently ([aacf900](https://github.com/revanced/revanced-patcher/commit/aacf9007647b1cc11bc40053625802573efda6ef))
### BREAKING CHANGES
* This changes the import paths for extension functions.
* This changes the names of extension functions
* This changes the name of functions
# [11.0.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v11.0.0-dev.1...v11.0.0-dev.2) (2023-06-09)
### Bug Fixes
* add imports to fix failing tests ([43d6868](https://github.com/revanced/revanced-patcher/commit/43d6868d1f59922f9812f3e4a2a890f3b331def6))
# [11.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v10.0.0...v11.0.0-dev.1) (2023-06-07) # [11.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v10.0.0...v11.0.0-dev.1) (2023-06-07)

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 11.0.0-dev.1 version = 11.0.2-dev.2

View File

@@ -23,6 +23,7 @@ import lanchon.multidexlib2.MultiDexIO
import org.jf.dexlib2.Opcodes import org.jf.dexlib2.Opcodes
import org.jf.dexlib2.iface.DexFile import org.jf.dexlib2.iface.DexFile
import org.jf.dexlib2.writer.io.MemoryDataStore import org.jf.dexlib2.writer.io.MemoryDataStore
import java.io.Closeable
import java.io.File import java.io.File
import java.io.OutputStream import java.io.OutputStream
import java.nio.file.Files import java.nio.file.Files
@@ -247,7 +248,13 @@ class Patcher(private val options: PatcherOptions) {
XmlPullStreamDecoder( XmlPullStreamDecoder(
axmlParser, AndrolibResources().resXmlSerializer axmlParser, AndrolibResources().resXmlSerializer
).decodeManifest( ).decodeManifest(
extInputFile.directory.getFileInput("AndroidManifest.xml"), OutputStream.nullOutputStream() extInputFile.directory.getFileInput("AndroidManifest.xml"),
// Older Android versions do not support OutputStream.nullOutputStream()
object : OutputStream() {
override fun write(b: Int) {
// do nothing
}
}
) )
} }
} }
@@ -255,7 +262,7 @@ class Patcher(private val options: PatcherOptions) {
// read of the resourceTable which is created by reading the manifest file // read of the resourceTable which is created by reading the manifest file
context.packageMetadata.let { metadata -> context.packageMetadata.let { metadata ->
metadata.packageName = resourceTable.currentResPackage.name metadata.packageName = resourceTable.currentResPackage.name
metadata.packageVersion = resourceTable.versionInfo.versionName metadata.packageVersion = resourceTable.versionInfo.versionName ?: resourceTable.versionInfo.versionCode
metadata.metaInfo.versionInfo = resourceTable.versionInfo metadata.metaInfo.versionInfo = resourceTable.versionInfo
metadata.metaInfo.sdkInfo = resourceTable.sdkInfo metadata.metaInfo.sdkInfo = resourceTable.sdkInfo
} }
@@ -345,24 +352,42 @@ class Patcher(private val options: PatcherOptions) {
val executedPatches = LinkedHashMap<String, ExecutedPatch>() // first is name val executedPatches = LinkedHashMap<String, ExecutedPatch>() // first is name
try {
context.patches.forEach { patch ->
val patchResult = executePatch(patch, executedPatches)
val result = if (patchResult.isSuccess()) { context.patches.forEach { patch ->
Result.success(patchResult.success()!!) val patchResult = executePatch(patch, executedPatches)
} else {
Result.failure(patchResult.error()!!)
}
yield(patch.patchName to result) val result = if (patchResult.isSuccess()) {
if (stopOnError && patchResult.isError()) return@sequence Result.success(patchResult.success()!!)
} } else {
} finally { Result.failure(patchResult.error()!!)
executedPatches.values.reversed().forEach { (patch, _) ->
patch.close()
} }
// TODO: This prints before the patch really finishes in case it is a Closeable
// because the Closeable is closed after all patches are executed.
yield(patch.patchName to result)
if (stopOnError && patchResult.isError()) return@sequence
} }
executedPatches.values
.filter(ExecutedPatch::success)
.map(ExecutedPatch::patchInstance)
.filterIsInstance(Closeable::class.java)
.asReversed().forEach {
try {
it.close()
} catch (exception: Exception) {
val patchName = (it as Patch<Context>).javaClass.patchName
logger.error("Failed to close '$patchName': ${exception.stackTraceToString()}")
yield(patchName to Result.failure(exception))
// This is not failsafe. If a patch throws an exception while closing,
// the other patches that depend on it may fail.
if (stopOnError) return@sequence
}
}
} }
} }

View File

@@ -12,7 +12,7 @@ import java.io.Closeable
* If it implements [Closeable], it will be closed after all patches have been executed. * If it implements [Closeable], it will be closed after all patches have been executed.
* Closing will be done in reverse execution order. * Closing will be done in reverse execution order.
*/ */
sealed interface Patch<out T : Context> : Closeable { sealed interface Patch<out T : Context> {
/** /**
* The main function of the [Patch] which the patcher will call. * The main function of the [Patch] which the patcher will call.
* *
@@ -20,13 +20,6 @@ sealed interface Patch<out T : Context> : Closeable {
* @return The result of executing the patch. * @return The result of executing the patch.
*/ */
fun execute(context: @UnsafeVariance T): PatchResult fun execute(context: @UnsafeVariance T): PatchResult
/**
* The closing function for this patch.
*
* This can be treated like popping the patch from the current patch stack.
*/
override fun close() {}
} }
/** /**

View File

@@ -1,5 +1,13 @@
package app.revanced.patcher.extensions package app.revanced.patcher.extensions
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
@@ -33,7 +41,7 @@ private object InstructionExtensionsTest {
).let { testMethod = it.toMutable() } ).let { testMethod = it.toMutable() }
@Test @Test
fun addInstructionsToImplementationIndexed() = applyOnImplementation { fun addInstructionsToImplementationIndexed() = applyToImplementation {
addInstructions(5, getTestInstructions(5..6)).also { addInstructions(5, getTestInstructions(5..6)).also {
assertRegisterIs(5, 5) assertRegisterIs(5, 5)
assertRegisterIs(6, 6) assertRegisterIs(6, 6)
@@ -43,7 +51,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addInstructionsToImplementation() = applyOnImplementation { fun addInstructionsToImplementation() = applyToImplementation {
addInstructions(getTestInstructions(10..11)).also { addInstructions(getTestInstructions(10..11)).also {
assertRegisterIs(10, 10) assertRegisterIs(10, 10)
assertRegisterIs(11, 11) assertRegisterIs(11, 11)
@@ -51,19 +59,19 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun removeInstructionsFromImplementationIndexed() = applyOnImplementation { fun removeInstructionsFromImplementationIndexed() = applyToImplementation {
removeInstructions(5, 5).also { assertRegisterIs(4, 4) } removeInstructions(5, 5).also { assertRegisterIs(4, 4) }
} }
@Test @Test
fun removeInstructionsFromImplementation() = applyOnImplementation { fun removeInstructionsFromImplementation() = applyToImplementation {
removeInstructions(0).also { assertRegisterIs(9, 9) } removeInstructions(0).also { assertRegisterIs(9, 9) }
removeInstructions(1).also { assertRegisterIs(1, 0) } removeInstructions(1).also { assertRegisterIs(1, 0) }
removeInstructions(2).also { assertRegisterIs(3, 0) } removeInstructions(2).also { assertRegisterIs(3, 0) }
} }
@Test @Test
fun replaceInstructionsInImplementationIndexed() = applyOnImplementation { fun replaceInstructionsInImplementationIndexed() = applyToImplementation {
replaceInstructions(5, getTestInstructions(0..1)).also { replaceInstructions(5, getTestInstructions(0..1)).also {
assertRegisterIs(0, 5) assertRegisterIs(0, 5)
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
@@ -72,27 +80,27 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addInstructionToMethodIndexed() = applyOnMethod { fun addInstructionToMethodIndexed() = applyToMethod {
addInstruction(5, TestInstruction(0)).also { assertRegisterIs(0, 5) } addInstruction(5, TestInstruction(0)).also { assertRegisterIs(0, 5) }
} }
@Test @Test
fun addInstructionToMethod() = applyOnMethod { fun addInstructionToMethod() = applyToMethod {
addInstruction(TestInstruction(0)).also { assertRegisterIs(0, 10) } addInstruction(TestInstruction(0)).also { assertRegisterIs(0, 10) }
} }
@Test @Test
fun addSmaliInstructionToMethodIndexed() = applyOnMethod { fun addSmaliInstructionToMethodIndexed() = applyToMethod {
addInstruction(5, getTestSmaliInstruction(0)).also { assertRegisterIs(0, 5) } addInstruction(5, getTestSmaliInstruction(0)).also { assertRegisterIs(0, 5) }
} }
@Test @Test
fun addSmaliInstructionToMethod() = applyOnMethod { fun addSmaliInstructionToMethod() = applyToMethod {
addInstruction(getTestSmaliInstruction(0)).also { assertRegisterIs(0, 10) } addInstruction(getTestSmaliInstruction(0)).also { assertRegisterIs(0, 10) }
} }
@Test @Test
fun addInstructionsToMethodIndexed() = applyOnMethod { fun addInstructionsToMethodIndexed() = applyToMethod {
addInstructions(5, getTestInstructions(0..1)).also { addInstructions(5, getTestInstructions(0..1)).also {
assertRegisterIs(0, 5) assertRegisterIs(0, 5)
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
@@ -102,7 +110,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addInstructionsToMethod() = applyOnMethod { fun addInstructionsToMethod() = applyToMethod {
addInstructions(getTestInstructions(0..1)).also { addInstructions(getTestInstructions(0..1)).also {
assertRegisterIs(0, 10) assertRegisterIs(0, 10)
assertRegisterIs(1, 11) assertRegisterIs(1, 11)
@@ -112,7 +120,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addSmaliInstructionsToMethodIndexed() = applyOnMethod { fun addSmaliInstructionsToMethodIndexed() = applyToMethod {
addInstructionsWithLabels(5, getTestSmaliInstructions(0..1)).also { addInstructionsWithLabels(5, getTestSmaliInstructions(0..1)).also {
assertRegisterIs(0, 5) assertRegisterIs(0, 5)
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
@@ -122,7 +130,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addSmaliInstructionsToMethod() = applyOnMethod { fun addSmaliInstructionsToMethod() = applyToMethod {
addInstructions(getTestSmaliInstructions(0..1)).also { addInstructions(getTestSmaliInstructions(0..1)).also {
assertRegisterIs(0, 10) assertRegisterIs(0, 10)
assertRegisterIs(1, 11) assertRegisterIs(1, 11)
@@ -132,8 +140,8 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun addSmaliInstructionsWithExternalLabelToMethodIndexed() = applyOnMethod { fun addSmaliInstructionsWithExternalLabelToMethodIndexed() = applyToMethod {
val label = ExternalLabel("testLabel", instruction(5)) val label = ExternalLabel("testLabel", getInstruction(5))
addInstructionsWithLabels( addInstructionsWithLabels(
5, 5,
@@ -144,7 +152,7 @@ private object InstructionExtensionsTest {
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
assertRegisterIs(5, 8) assertRegisterIs(5, 8)
val gotoTarget = instruction<BuilderOffsetInstruction>(7) val gotoTarget = getInstruction<BuilderOffsetInstruction>(7)
.target.location.instruction as OneRegisterInstruction .target.location.instruction as OneRegisterInstruction
assertEquals(5, gotoTarget.registerA) assertEquals(5, gotoTarget.registerA)
@@ -152,7 +160,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun removeInstructionFromMethodIndexed() = applyOnMethod { fun removeInstructionFromMethodIndexed() = applyToMethod {
removeInstruction(5).also { removeInstruction(5).also {
assertRegisterIs(4, 4) assertRegisterIs(4, 4)
assertRegisterIs(6, 5) assertRegisterIs(6, 5)
@@ -160,24 +168,24 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun removeInstructionsFromMethodIndexed() = applyOnMethod { fun removeInstructionsFromMethodIndexed() = applyToMethod {
removeInstructions(5, 5).also { assertRegisterIs(4, 4) } removeInstructions(5, 5).also { assertRegisterIs(4, 4) }
} }
@Test @Test
fun removeInstructionsFromMethod() = applyOnMethod { fun removeInstructionsFromMethod() = applyToMethod {
removeInstructions(0).also { assertRegisterIs(9, 9) } removeInstructions(0).also { assertRegisterIs(9, 9) }
removeInstructions(1).also { assertRegisterIs(1, 0) } removeInstructions(1).also { assertRegisterIs(1, 0) }
removeInstructions(2).also { assertRegisterIs(3, 0) } removeInstructions(2).also { assertRegisterIs(3, 0) }
} }
@Test @Test
fun replaceInstructionInMethodIndexed() = applyOnMethod { fun replaceInstructionInMethodIndexed() = applyToMethod {
replaceInstruction(5, TestInstruction(0)).also { assertRegisterIs(0, 5) } replaceInstruction(5, TestInstruction(0)).also { assertRegisterIs(0, 5) }
} }
@Test @Test
fun replaceInstructionsInMethodIndexed() = applyOnMethod { fun replaceInstructionsInMethodIndexed() = applyToMethod {
replaceInstructions(5, getTestInstructions(0..1)).also { replaceInstructions(5, getTestInstructions(0..1)).also {
assertRegisterIs(0, 5) assertRegisterIs(0, 5)
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
@@ -186,7 +194,7 @@ private object InstructionExtensionsTest {
} }
@Test @Test
fun replaceSmaliInstructionsInMethodIndexed() = applyOnMethod { fun replaceSmaliInstructionsInMethodIndexed() = applyToMethod {
replaceInstructions(5, getTestSmaliInstructions(0..1)).also { replaceInstructions(5, getTestSmaliInstructions(0..1)).also {
assertRegisterIs(0, 5) assertRegisterIs(0, 5)
assertRegisterIs(1, 6) assertRegisterIs(1, 6)
@@ -196,16 +204,16 @@ private object InstructionExtensionsTest {
// region Helper methods // region Helper methods
private fun applyOnImplementation(block: MutableMethodImplementation.() -> Unit) { private fun applyToImplementation(block: MutableMethodImplementation.() -> Unit) {
testMethodImplementation.apply(block) testMethodImplementation.apply(block)
} }
private fun applyOnMethod(block: MutableMethod.() -> Unit) { private fun applyToMethod(block: MutableMethod.() -> Unit) {
testMethod.apply(block) testMethod.apply(block)
} }
private fun MutableMethodImplementation.assertRegisterIs(register: Int, atIndex: Int) = assertEquals( private fun MutableMethodImplementation.assertRegisterIs(register: Int, atIndex: Int) = assertEquals(
register, instruction<OneRegisterInstruction>(atIndex).registerA register, getInstruction<OneRegisterInstruction>(atIndex).registerA
) )
private fun MutableMethod.assertRegisterIs(register: Int, atIndex: Int) = private fun MutableMethod.assertRegisterIs(register: Int, atIndex: Int) =