This commit is contained in:
kunfei 2023-04-21 00:17:59 +08:00
parent 41eacf72fc
commit 1dbe4b4ec0
7 changed files with 175 additions and 181 deletions

View File

@ -10,13 +10,18 @@ import android.os.Build
import com.github.liuyueyi.quick.transfer.ChineseUtils
import com.github.liuyueyi.quick.transfer.constants.TransType
import com.jeremyliao.liveeventbus.LiveEventBus
import com.script.rhino.RhinoScriptEngine
import io.legado.app.base.AppContextWrapper
import io.legado.app.constant.AppConst.channelIdDownload
import io.legado.app.constant.AppConst.channelIdReadAloud
import io.legado.app.constant.AppConst.channelIdWeb
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.help.*
import io.legado.app.help.AppWebDav
import io.legado.app.help.CrashHandler
import io.legado.app.help.DefaultData
import io.legado.app.help.LifecycleHelp
import io.legado.app.help.RuleBigDataHelp
import io.legado.app.help.book.BookHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ThemeConfig.applyDayNight
@ -36,6 +41,7 @@ class App : Application() {
override fun onCreate() {
super.onCreate()
RhinoScriptEngine
oldConfig = Configuration(resources.configuration)
CrashHandler(this)
//预下载Cronet so

View File

@ -1,6 +1,8 @@
package io.legado.app.data.entities
import cn.hutool.crypto.symmetric.AES
import com.script.SimpleBindings
import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog
import io.legado.app.data.entities.rule.RowUi
@ -10,9 +12,6 @@ import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.CookieStore
import io.legado.app.model.SharedJsScope
import io.legado.app.rhino.Bindings
import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate
import io.legado.app.rhino.putBindings
import io.legado.app.utils.*
import org.intellij.lang.annotations.Language
import org.mozilla.javascript.Scriptable
@ -237,14 +236,15 @@ interface BaseSource : JsExtensions {
bindings["baseUrl"] = getKey()
bindings["cookie"] = CookieStore
bindings["cache"] = CacheManager
return Rhino.use {
val scope = initStandardObjects()
scope.putBindings(bindings)
getShareScope()?.let {
scope.prototype = it
}
evaluate(scope, jsStr)
}
// return Rhino.use {
// val scope = initStandardObjects()
// scope.putBindings(bindings)
// getShareScope()?.let {
// scope.prototype = it
// }
// evaluate(scope, jsStr)
// }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings))
}
fun getShareScope(): Scriptable? {

View File

@ -2,6 +2,8 @@ package io.legado.app.model.analyzeRule
import android.text.TextUtils
import androidx.annotation.Keep
import com.script.SimpleBindings
import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppPattern.JS_PATTERN
import io.legado.app.data.entities.*
import io.legado.app.help.CacheManager
@ -9,9 +11,6 @@ import io.legado.app.help.JsExtensions
import io.legado.app.help.http.CookieStore
import io.legado.app.model.webBook.WebBook
import io.legado.app.rhino.Bindings
import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate
import io.legado.app.rhino.putBindings
import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
@ -695,14 +694,15 @@ class AnalyzeRule(
bindings["title"] = chapter?.title
bindings["src"] = content
bindings["nextChapterUrl"] = nextChapterUrl
return Rhino.use {
val scope = initStandardObjects()
scope.putBindings(bindings)
source?.getShareScope()?.let {
scope.prototype = it
}
evaluate(scope, jsStr)
}
// return Rhino.use {
// val scope = initStandardObjects()
// scope.putBindings(bindings)
// source?.getShareScope()?.let {
// scope.prototype = it
// }
// evaluate(scope, jsStr)
// }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings))
}
override fun getSource(): BaseSource? {

View File

@ -5,6 +5,8 @@ import android.util.Base64
import androidx.annotation.Keep
import cn.hutool.core.util.HexUtil
import com.bumptech.glide.load.model.GlideUrl
import com.script.SimpleBindings
import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppConst.UA_NAME
import io.legado.app.constant.AppPattern
import io.legado.app.constant.AppPattern.JS_PATTERN
@ -19,9 +21,6 @@ import io.legado.app.help.config.AppConfig
import io.legado.app.help.glide.GlideHeaders
import io.legado.app.help.http.*
import io.legado.app.rhino.Bindings
import io.legado.app.rhino.Rhino
import io.legado.app.rhino.evaluate
import io.legado.app.rhino.putBindings
import io.legado.app.utils.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
@ -267,14 +266,15 @@ class AnalyzeUrl(
bindings["book"] = ruleData as? Book
bindings["source"] = source
bindings["result"] = result
return Rhino.use {
val scope = initStandardObjects()
scope.putBindings(bindings)
source?.getShareScope()?.let {
scope.prototype = it
}
evaluate(scope, jsStr)
}
// return Rhino.use {
// val scope = initStandardObjects()
// scope.putBindings(bindings)
// source?.getShareScope()?.let {
// scope.prototype = it
// }
// evaluate(scope, jsStr)
// }
return RhinoScriptEngine.eval(jsStr, SimpleBindings(bindings))
}
fun put(key: String, value: String): String {

View File

@ -1,8 +1,6 @@
package io.legado.app.rhino
import com.script.RhinoContextFactory
import org.mozilla.javascript.Context
import org.mozilla.javascript.ContextFactory
import org.mozilla.javascript.Undefined
import org.mozilla.javascript.Wrapper
@ -25,19 +23,18 @@ object Rhino {
return if (result1 is Undefined) null else result1
}
init {
ContextFactory.initGlobal(object : RhinoContextFactory() {
override fun makeContext(): Context {
val cx = super.makeContext()
cx.languageVersion = 200
cx.optimizationLevel = -1
cx.setClassShutter(RhinoClassShutter)
//cx.wrapFactory = RhinoWrapFactory
return cx
}
})
}
// init {
// ContextFactory.initGlobal(object : RhinoContextFactory() {
//
// override fun makeContext(): Context {
// val cx = super.makeContext()
// cx.languageVersion = 200
// cx.optimizationLevel = -1
// cx.setClassShutter(RhinoClassShutter)
// return cx
// }
//
// })
// }
}

View File

@ -42,7 +42,7 @@ import java.security.*
* @since 1.6
*/
@Suppress("MemberVisibilityCanBePrivate")
class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
var accessContext: AccessControlContext? = null
private var topLevel: RhinoTopLevel? = null
private val indexedProps: MutableMap<Any, Any?>
@ -198,6 +198,62 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
}
init {
ContextFactory.initGlobal(object : ContextFactory() {
override fun makeContext(): Context {
val cx = super.makeContext()
cx.languageVersion = 200
cx.optimizationLevel = -1
cx.setClassShutter(RhinoClassShutter)
cx.wrapFactory = RhinoWrapFactory
return cx
}
override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
@Suppress("UNUSED_EXPRESSION")
return when (featureIndex) {
//Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
else -> super.hasFeature(cx, featureIndex)
}
}
override fun doTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
var accContext: AccessControlContext? = null
val global = ScriptableObject.getTopLevelScope(scope)
val globalProto = global.prototype
if (globalProto is RhinoTopLevel) {
accContext = globalProto.accessContext
}
return if (accContext != null) AccessController.doPrivileged(
PrivilegedAction {
superDoTopCall(callable, cx, scope, thisObj, args)
}, accContext
) else superDoTopCall(
callable,
cx,
scope,
thisObj,
args
)
}
private fun superDoTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
return super.doTopCall(callable, cx, scope, thisObj, args)
}
})
if (System.getSecurityManager() != null) {
try {
AccessController.checkPermission(AllPermission())
@ -251,65 +307,4 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
}
}
@Suppress("unused")
companion object {
init {
ContextFactory.initGlobal(object : ContextFactory() {
override fun makeContext(): Context {
val cx = super.makeContext()
cx.languageVersion = 200
cx.optimizationLevel = -1
cx.setClassShutter(RhinoClassShutter)
cx.wrapFactory = RhinoWrapFactory
return cx
}
override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
@Suppress("UNUSED_EXPRESSION")
return when (featureIndex) {
//Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
else -> super.hasFeature(cx, featureIndex)
}
}
override fun doTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
var accContext: AccessControlContext? = null
val global = ScriptableObject.getTopLevelScope(scope)
val globalProto = global.prototype
if (globalProto is RhinoTopLevel) {
accContext = globalProto.accessContext
}
return if (accContext != null) AccessController.doPrivileged(
PrivilegedAction {
superDoTopCall(callable, cx, scope, thisObj, args)
}, accContext
) else superDoTopCall(
callable,
cx,
scope,
thisObj,
args
)
}
private fun superDoTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
return super.doTopCall(callable, cx, scope, thisObj, args)
}
})
}
}
}

View File

@ -34,15 +34,15 @@ import java.lang.reflect.Method
import java.security.*
/**
* Implementation of `ScriptEngine` using the Mozilla Rhino
* interpreter.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
@Suppress("MemberVisibilityCanBePrivate")
class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
* Implementation of `ScriptEngine` using the Mozilla Rhino
* interpreter.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
@Suppress("MemberVisibilityCanBePrivate")
object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
var accessContext: AccessControlContext? = null
private var topLevel: RhinoTopLevel? = null
private val indexedProps: MutableMap<Any, Any?>
@ -198,6 +198,62 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
}
init {
ContextFactory.initGlobal(object : ContextFactory() {
override fun makeContext(): Context {
val cx = super.makeContext()
cx.languageVersion = 200
cx.optimizationLevel = -1
cx.setClassShutter(RhinoClassShutter)
cx.wrapFactory = RhinoWrapFactory
return cx
}
override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
return when (featureIndex) {
Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
else -> super.hasFeature(cx, featureIndex)
}
}
override fun doTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
var accContext: AccessControlContext? = null
val global = ScriptableObject.getTopLevelScope(scope)
val globalProto = global.prototype
if (globalProto is RhinoTopLevel) {
accContext = globalProto.accessContext
}
return if (accContext != null) AccessController.doPrivileged(
PrivilegedAction {
superDoTopCall(callable, cx, scope, thisObj, args)
}, accContext
) else superDoTopCall(
callable,
cx,
scope,
thisObj,
args
)
}
private fun superDoTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
return super.doTopCall(callable, cx, scope, thisObj, args)
}
})
if (System.getSecurityManager() != null) {
try {
AccessController.checkPermission(AllPermission())
@ -251,64 +307,4 @@ class RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
}
}
@Suppress("unused")
companion object {
init {
ContextFactory.initGlobal(object : ContextFactory() {
override fun makeContext(): Context {
val cx = super.makeContext()
cx.languageVersion = 200
cx.optimizationLevel = -1
cx.setClassShutter(RhinoClassShutter)
cx.wrapFactory = RhinoWrapFactory
return cx
}
override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
return when (featureIndex) {
Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
else -> super.hasFeature(cx, featureIndex)
}
}
override fun doTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
var accContext: AccessControlContext? = null
val global = ScriptableObject.getTopLevelScope(scope)
val globalProto = global.prototype
if (globalProto is RhinoTopLevel) {
accContext = globalProto.accessContext
}
return if (accContext != null) AccessController.doPrivileged(
PrivilegedAction {
superDoTopCall(callable, cx, scope, thisObj, args)
}, accContext
) else superDoTopCall(
callable,
cx,
scope,
thisObj,
args
)
}
private fun superDoTopCall(
callable: Callable,
cx: Context,
scope: Scriptable,
thisObj: Scriptable,
args: Array<Any>
): Any? {
return super.doTopCall(callable, cx, scope, thisObj, args)
}
})
}
}
}