This commit is contained in:
kunfei
2023-04-20 21:22:24 +08:00
parent f1eccda865
commit 863b41ac4f
8 changed files with 146 additions and 21 deletions
@@ -1,11 +1,11 @@
package io.legado.app package io.legado.app
import io.legado.app.constant.SCRIPT_ENGINE import io.legado.app.rhino.Rhino
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
class JsTest { class AndroidJsTest {
@Test @Test
fun testPackages() { fun testPackages() {
@@ -35,14 +35,26 @@ class JsTest {
var queryStringWithSign = "Signature=" + signStr + "&" + query; var queryStringWithSign = "Signature=" + signStr + "&" + query;
queryStringWithSign queryStringWithSign
""".trimIndent() """.trimIndent()
SCRIPT_ENGINE.eval(js) Rhino.use {
evaluateString(initStandardObjects(), js, "yy", 1, null)
}
@Language("js") @Language("js")
val js1 = """ val js1 = """
var returnData = new Packages.io.legado.app.api.ReturnData() var returnData = new Packages.io.legado.app.api.ReturnData()
returnData.getErrorMsg() returnData.getErrorMsg()
""".trimIndent() """.trimIndent()
val result1 = SCRIPT_ENGINE.eval(js1) val result1 = Rhino.use {
evaluateString(initStandardObjects(), js1, "xx", 1, null)
}
Assert.assertEquals(result1, "未知错误,请联系开发者!") Assert.assertEquals(result1, "未知错误,请联系开发者!")
} }
@Test
fun testReturnNull() {
val result = Rhino.use {
evaluateString(initStandardObjects(), "null", "xx", 1, null)
}
Assert.assertEquals(null, result)
}
} }
@@ -6,10 +6,10 @@ import io.legado.app.constant.SCRIPT_ENGINE
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.http.newCallStrResponse import io.legado.app.help.http.newCallStrResponse
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.rhino.Rhino
import io.legado.app.utils.ACache import io.legado.app.utils.ACache
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.Rhino
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isJsonObject import io.legado.app.utils.isJsonObject
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@@ -0,0 +1,44 @@
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
object Rhino {
inline fun use(block: Context.() -> Any?): Any? {
return try {
val cx = Context.enter()
val result = block.invoke(cx)
unwrapReturnValue(result)
} finally {
Context.exit()
}
}
fun unwrapReturnValue(result: Any?): Any? {
var result1 = result
if (result1 is Wrapper) {
result1 = result1.unwrap()
}
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
}
})
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package io.legado.app.rhino
import org.mozilla.javascript.ClassShutter
/**
* This class prevents script access to certain sensitive classes.
* Note that this class checks over and above SecurityManager. i.e., although
* a SecurityManager would pass, class shutter may still prevent access.
*
* @author A. Sundararajan
* @since 1.6
*/
object RhinoClassShutter : ClassShutter {
private val protectedClasses by lazy {
val protectedClasses = HashMap<Any, Any>()
protectedClasses["java.lang.Runtime"] = java.lang.Boolean.TRUE
protectedClasses["java.io.File"] = java.lang.Boolean.TRUE
protectedClasses["java.security.AccessController"] = java.lang.Boolean.TRUE
protectedClasses
}
override fun visibleToScripts(fullClassName: String): Boolean {
val sm = System.getSecurityManager()
if (sm != null) {
val i = fullClassName.lastIndexOf(".")
if (i != -1) {
try {
sm.checkPackageAccess(fullClassName.substring(0, i))
} catch (e: SecurityException) {
return false
}
}
}
return protectedClasses[fullClassName] == null
}
}
@@ -1,15 +0,0 @@
package io.legado.app.utils
import org.mozilla.javascript.Context
object Rhino {
inline fun <R> use(block: Context.() -> R): R {
return try {
block.invoke(Context.enter())
} finally {
Context.exit()
}
}
}
@@ -0,0 +1,7 @@
package com.script
import org.mozilla.javascript.ContextFactory
open class RhinoContextFactory : ContextFactory() {
}
@@ -0,0 +1,15 @@
package com.script
import org.mozilla.javascript.Context
import org.mozilla.javascript.ContextFactory
open class RhinoContextFactory : ContextFactory() {
override fun hasFeature(cx: Context, featureIndex: Int): Boolean {
return when (featureIndex) {
Context.FEATURE_ENABLE_JAVA_MAP_ACCESS -> true
else -> super.hasFeature(cx, featureIndex)
}
}
}
@@ -51,7 +51,7 @@ object RhinoClassShutter : ClassShutter {
if (i != -1) { if (i != -1) {
try { try {
sm.checkPackageAccess(fullClassName.substring(0, i)) sm.checkPackageAccess(fullClassName.substring(0, i))
} catch (var5: SecurityException) { } catch (e: SecurityException) {
return false return false
} }
} }