kunfei 3 лет назад
Родитель
Сommit
f817954b7c

+ 16 - 4
app/src/androidTest/java/io/legado/app/JsTest.kt → app/src/androidTest/java/io/legado/app/AndroidJsTest.kt

@@ -1,11 +1,11 @@
 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.junit.Assert
 import org.junit.Test
 
-class JsTest {
+class AndroidJsTest {
 
     @Test
     fun testPackages() {
@@ -35,14 +35,26 @@ class JsTest {
             var queryStringWithSign = "Signature=" + signStr + "&" + query;
             queryStringWithSign
         """.trimIndent()
-        SCRIPT_ENGINE.eval(js)
+        Rhino.use {
+            evaluateString(initStandardObjects(), js, "yy", 1, null)
+        }
         @Language("js")
         val js1 = """
             var returnData = new Packages.io.legado.app.api.ReturnData()
             returnData.getErrorMsg()
         """.trimIndent()
-        val result1 = SCRIPT_ENGINE.eval(js1)
+        val result1 = Rhino.use {
+            evaluateString(initStandardObjects(), js1, "xx", 1, null)
+        }
         Assert.assertEquals(result1, "未知错误,请联系开发者!")
     }
 
+    @Test
+    fun testReturnNull() {
+        val result = Rhino.use {
+            evaluateString(initStandardObjects(), "null", "xx", 1, null)
+        }
+        Assert.assertEquals(null, result)
+    }
+
 }

+ 1 - 1
app/src/main/java/io/legado/app/model/SharedJsScope.kt

@@ -6,10 +6,10 @@ import io.legado.app.constant.SCRIPT_ENGINE
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.http.newCallStrResponse
 import io.legado.app.help.http.okHttpClient
+import io.legado.app.rhino.Rhino
 import io.legado.app.utils.ACache
 import io.legado.app.utils.GSON
 import io.legado.app.utils.MD5Utils
-import io.legado.app.utils.Rhino
 import io.legado.app.utils.isAbsUrl
 import io.legado.app.utils.isJsonObject
 import kotlinx.coroutines.runBlocking

+ 44 - 0
app/src/main/java/io/legado/app/rhino/Rhino.kt

@@ -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
+            }
+
+        })
+    }
+
+}

+ 62 - 0
app/src/main/java/io/legado/app/rhino/RhinoClassShutter.kt

@@ -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
+    }
+
+}

+ 0 - 15
app/src/main/java/io/legado/app/utils/Rhino.kt

@@ -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()
-        }
-    }
-
-}

+ 7 - 0
modules/rhino1.7.3/src/main/java/com/script/RhinoContextFactory.kt

@@ -0,0 +1,7 @@
+package com.script
+
+import org.mozilla.javascript.ContextFactory
+
+open class RhinoContextFactory : ContextFactory() {
+
+}

+ 15 - 0
modules/rhino1.7.4/src/main/java/com/script/RhinoContextFactory.kt

@@ -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)
+        }
+    }
+
+}

+ 1 - 1
modules/rhino1.7.4/src/main/java/com/script/rhino/RhinoClassShutter.kt

@@ -51,7 +51,7 @@ object RhinoClassShutter : ClassShutter {
             if (i != -1) {
                 try {
                     sm.checkPackageAccess(fullClassName.substring(0, i))
-                } catch (var5: SecurityException) {
+                } catch (e: SecurityException) {
                     return false
                 }
             }