From 49fac78fec0ec512cf125af9b906d0987867faca Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Mon, 13 Jan 2025 01:30:56 +0800 Subject: [PATCH] =?UTF-8?q?6.6.2=20-=20Alpha=20-=20=E4=BF=AE=E5=A4=8D=20pl?= =?UTF-8?q?ugins.load;=20=E4=BC=98=E5=8C=96=20dex=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=96=B9=E5=BC=8F=20(issue=20#290)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 4 ++- .../autojs/autojs/rhino/AndroidClassLoader.kt | 33 ++++++++++++++----- .../runtime/api/augment/plugins/Plugins.kt | 8 +++-- .../java/org/autojs/autojs/util/MD5Utils.kt | 15 +++++++++ version.properties | 6 ++-- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index c22bf48d..d126207c 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -3,9 +3,11 @@ "v6.6.2": { "released_date": "2025/01/03", "fix": [ - "notice 模块缺失 getBuilder 等扩展方法的问题 _[`issue #301`](http://issues.autojs6.com/301)_", + "plugins.load 方法无法正常加载插件的问题 _[`issue #290`](http://issues.autojs6.com/290)_", + "dex 文件可能因权限问题无法正常加载的问题 (试修) _[`issue #290`](http://issues.autojs6.com/290)_", "dx 库在 Android 7.x 无法正常使用的问题 _[`issue #293`](http://issues.autojs6.com/293)_", "ScriptRuntime 使用 require 引用内置模块时可能出现的同步状态异常 (试修)_[`issue #298`](http://issues.autojs6.com/298)_", + "notice 模块缺失 getBuilder 等扩展方法的问题 _[`issue #301`](http://issues.autojs6.com/301)_", "floaty.window/floaty.rawWindow 无法在子线程执行的问题" ], "improvement": [ diff --git a/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt b/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt index fb1209b3..b9e2c95d 100644 --- a/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt +++ b/app/src/main/java/org/autojs/autojs/rhino/AndroidClassLoader.kt @@ -3,7 +3,6 @@ package org.autojs.autojs.rhino import android.os.Build import android.util.Log import com.android.dx.command.dexer.Main -import com.legacy.android.dx.command.dexer.Main as LegacyMain import dalvik.system.DexClassLoader import net.lingala.zip4j.ZipFile import net.lingala.zip4j.exception.ZipException @@ -17,6 +16,7 @@ import java.io.ByteArrayInputStream import java.io.File import java.io.FileNotFoundException import java.io.IOException +import com.legacy.android.dx.command.dexer.Main as LegacyMain /** * Created by Stardust on Apr 5, 2017. @@ -50,22 +50,37 @@ class AndroidClassLoader(private val parent: ClassLoader, private val cacheDir: @Throws(FileNotFoundException::class) fun loadDex(file: File): DexClassLoader { - val path = file.path - Log.d(TAG, "loadDex: file = $path") + val originalPath = file.path + Log.d(TAG, "loadDex: file = $originalPath") + if (!file.exists() || !file.canRead()) { - throw FileNotFoundException(str(R.string.file_not_exist_or_readable, path)) + throw FileNotFoundException(str(R.string.file_not_exist_or_readable, originalPath)) } // @Hint by SuperMonster003 on Nov 30, 2023. // ! Try to avoid the exception which looks like below (API Level 34+): // # java.lang.SecurityException: Writable dex file '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar' is not allowed. - // ! zh-CN: - // ! 尝试避免如下异常 (API 级别 34+): + // ! zh-CN: 尝试避免如下异常 (API 级别 34+): // # java.lang.SecurityException: 不允许可写的 dex 文件 '/data/user/0/org.autojs.autojs6/cache/classes/xxx.jar'. - file.setReadOnly() + // ! + // @Hint by SuperMonster003 on Jan 13, 2025. + // ! Copy the dex file to the cache path and set it as read-only. + // ! zh-CN: 将 dex 文件复制到缓存路径并设置只读. + // # file.setReadOnly() + val safeDexFile = File(cacheDir, "safe_${file.name}") + try { + if (!safeDexFile.exists() || md5(file) != md5(safeDexFile)) { + file.copyTo(safeDexFile, overwrite = true) + } + if (!safeDexFile.setReadOnly()) { + Log.e(TAG, "Failed to set file as read-only: ${safeDexFile.path}") + } + } catch (e: IOException) { + throw FatalLoadingException(e) + } - return DexClassLoader(path, cacheDir.path, null, parent).also { - mDexClassLoaders[path] = it + return DexClassLoader(safeDexFile.path, cacheDir.path, null, parent).also { + mDexClassLoaders[safeDexFile.path] = it } } diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/plugins/Plugins.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/plugins/Plugins.kt index fa8e2f0a..b77331b8 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/plugins/Plugins.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/plugins/Plugins.kt @@ -4,6 +4,7 @@ import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface import org.autojs.autojs.extension.FlexibleArray import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.api.augment.Augmentable +import org.autojs.autojs.runtime.api.augment.Invokable import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.util.RhinoUtils.callFunction import org.autojs.autojs.util.RhinoUtils.coerceString @@ -12,18 +13,21 @@ import org.mozilla.javascript.BaseFunction import kotlin.text.RegexOption.IGNORE_CASE @Suppress("unused", "UNUSED_PARAMETER") -class Plugins(scriptRuntime: ScriptRuntime) : Augmentable() { +class Plugins(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable { override val selfAssignmentFunctions = listOf( ::load.name, ) + override fun invoke(vararg args: Any?): Any? = ensureArgumentsOnlyOne(args) { o -> + load(scriptRuntime, arrayOf(o)) + } + companion object : FlexibleArray() { @JvmStatic @RhinoRuntimeFunctionInterface fun load(scriptRuntime: ScriptRuntime, args: Array): Any? = ensureArgumentsOnlyOne(args) { o -> - // require(o is String) { "Argument name for plugins.load must be a string" } val name = coerceString(o) val asPackageName = name.contains('.') && !name.matches(Regex(".+\\.js", IGNORE_CASE)) when { diff --git a/app/src/main/java/org/autojs/autojs/util/MD5Utils.kt b/app/src/main/java/org/autojs/autojs/util/MD5Utils.kt index f1ce8cc0..be104d26 100644 --- a/app/src/main/java/org/autojs/autojs/util/MD5Utils.kt +++ b/app/src/main/java/org/autojs/autojs/util/MD5Utils.kt @@ -1,6 +1,8 @@ package org.autojs.autojs.util import android.util.Base64 +import java.io.File +import java.io.FileInputStream import java.security.MessageDigest import java.security.NoSuchAlgorithmException @@ -26,6 +28,19 @@ object MD5Utils { } } + @JvmStatic + fun md5(file: File): String { + val buffer = ByteArray(1024) + val digest = MessageDigest.getInstance("MD5") + FileInputStream(file).use { fis -> + var numRead: Int + while (fis.read(buffer).also { numRead = it } > 0) { + digest.update(buffer, 0, numRead) + } + } + return digest.digest().joinToString("") { "%02x".format(it) } + } + @JvmStatic fun toHash(text: String): String = try { MessageDigest.getInstance("MD5") diff --git a/version.properties b/version.properties index 319d1a6c..2ea6f224 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Sun Jan 12 23:32:51 CST 2025 -BUILD_TIME=1736695971805 +#Mon Jan 13 01:22:59 CST 2025 +BUILD_TIME=1736702579820 COMPILE_SDK_VERSION=34 JAVA_VERSION=23 JAVA_VERSION_MIN_RADICAL=0 @@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 TARGET_SDK_VERSION=34 TARGET_SDK_VERSION_INRT=29 -VERSION_BUILD=2966 +VERSION_BUILD=2967 VERSION_NAME=6.6.2 Alpha VSCODE_EXT_REQUIRED_VERSION=1.0.8