This commit is contained in:
kunfei 2023-06-15 16:26:21 +08:00
parent 08cab46033
commit 651f3cc460
28 changed files with 45 additions and 2079 deletions

View File

@ -1,10 +1,14 @@
package io.legado.app package io.legado.app
import cn.hutool.core.lang.JarClassLoader
import com.script.SimpleBindings import com.script.SimpleBindings
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import dalvik.system.DexClassLoader
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
import org.mozilla.javascript.DefiningClassLoader
import java.net.URLClassLoader
class AndroidJsTest { class AndroidJsTest {
@ -44,11 +48,22 @@ class AndroidJsTest {
""".trimIndent() """.trimIndent()
val result1 = RhinoScriptEngine.eval(js1) val result1 = RhinoScriptEngine.eval(js1)
Assert.assertEquals(result1, "未知错误,请联系开发者!") Assert.assertEquals(result1, "未知错误,请联系开发者!")
}
@Test
fun testPackages1() {
URLClassLoader.getSystemClassLoader()
DefiningClassLoader.getSystemClassLoader()
JarClassLoader.getSystemClassLoader()
DexClassLoader.getSystemClassLoader()
@Language("js") @Language("js")
val js2 = """ val js = """
let x = java.lang.Class.forName('android.app.ActivityThread') var ji = new JavaImporter(Packages.org.mozilla.javascript.DefiningClassLoader)
with(ji) {
let x = DefiningClassLoader.getSystemClassLoader()
}
""".trimIndent() """.trimIndent()
RhinoScriptEngine.eval(js2) RhinoScriptEngine.eval(js)
} }
@Test @Test

View File

@ -37,36 +37,39 @@ import org.mozilla.javascript.ClassShutter
object RhinoClassShutter : ClassShutter { object RhinoClassShutter : ClassShutter {
private val protectedClasses by lazy { private val protectedClasses by lazy {
val protectedClasses = HashMap<Any, Any>() hashSetOf(
protectedClasses["java.lang.Class"] = true "dalvik.system",
protectedClasses["java.lang.ClassLoader"] = true "org.mozilla.javascript",
protectedClasses["java.lang.Runtime"] = true "java.lang.Class",
protectedClasses["java.io.File"] = true "java.lang.ClassLoader",
protectedClasses["java.security.AccessController"] = true "java.net.URLClassLoader",
protectedClasses["java.nio.file.Paths"] = true "cn.hutool.core.lang.JarClassLoader",
protectedClasses["java.nio.file.Files"] = true "java.lang.Runtime",
protectedClasses["io.legado.app.data.AppDatabaseKt"] = true "java.io.File",
protectedClasses["io.legado.app.utils.ContextExtensionsKt"] = true "java.security.AccessController",
protectedClasses["android.content.Intent"] = true "java.nio.file.Paths",
protectedClasses["androidx.core.content.FileProvider"] = true "java.nio.file.Files",
protectedClasses["android.provider.Settings"] = true "io.legado.app.data.AppDatabaseKt",
protectedClasses["androidx.sqlite.db"] = true "io.legado.app.utils.ContextExtensionsKt",
protectedClasses "android.content.Intent",
"androidx.core.content.FileProvider",
"android.provider.Settings",
"androidx.sqlite.db",
)
} }
override fun visibleToScripts(fullClassName: String): Boolean { override fun visibleToScripts(fullClassName: String): Boolean {
val sm = System.getSecurityManager() if (!protectedClasses.contains(fullClassName)) {
if (sm != null) { var className = fullClassName
val i = fullClassName.lastIndexOf(".") while (className.contains(".")) {
if (i != -1) { className = className.substringBeforeLast(".")
try { if (protectedClasses.contains(className)) {
sm.checkPackageAccess(fullClassName.substring(0, i))
} catch (var5: SecurityException) {
return false return false
} }
} }
return true
} }
return protectedClasses[fullClassName] == null return false
} }
} }

View File

@ -1 +0,0 @@
/build

View File

@ -1,35 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk = compile_sdk_version
namespace 'com.script'
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
defaultConfig {
minSdk 24
targetSdk 33
consumerProguardFiles "consumer-rules.pro"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
lint {
checkDependencies true
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
}
}
dependencies {
api(fileTree(dir: 'lib', include: ['rhino-1.7.14-2.jar']))
}

View File

@ -1,31 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
## Rhino
-keep class com.script.** { *; }
-keep class javax.script.** { *; }
-keep class java.lang.** { *; }
-keep class java.util.function.** { *; }
-keep class com.sun.script.javascript.** { *; }
-keep class org.mozilla.** { *; }
-dontwarn org.mozilla.javascript.engine.RhinoScriptEngineFactory

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
</manifest>

View File

@ -1,98 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
import org.mozilla.javascript.Scriptable
import java.io.Reader
import java.io.StringReader
abstract class AbstractScriptEngine(val bindings: Bindings? = null) : ScriptEngine {
override var context: ScriptContext = SimpleScriptContext()
init {
bindings?.let {
context.setBindings(bindings, 100)
}
}
override fun getBindings(scope: Int): Bindings? {
if (scope == 200) {
return context.getBindings(200)
}
if (scope == 100) {
return context.getBindings(100)
}
throw IllegalArgumentException("Invalid scope value.")
}
override fun setBindings(bindings: Bindings?, scope: Int) {
when (scope) {
200 -> {
context.setBindings(bindings, 200)
}
100 -> {
context.setBindings(bindings, 100)
}
else -> {
throw IllegalArgumentException("Invalid scope value.")
}
}
}
override fun put(key: String, value: Any?) {
getBindings(100)?.put(key, value)
}
override fun get(key: String): Any? {
return getBindings(100)?.get(key)
}
override fun eval(script: String, scope: Scriptable): Any? {
return this.eval(StringReader(script), scope)
}
@Throws(ScriptException::class)
override fun eval(reader: Reader, context: ScriptContext): Any? {
return this.eval(reader, getRuntimeScope(context))
}
@Throws(ScriptException::class)
override fun eval(reader: Reader, bindings: Bindings): Any? {
return this.eval(reader, getScriptContext(bindings))
}
@Throws(ScriptException::class)
override fun eval(script: String, bindings: Bindings): Any? {
return this.eval(script, getScriptContext(bindings))
}
@Throws(ScriptException::class)
override fun eval(reader: Reader): Any? {
return this.eval(reader, context)
}
@Throws(ScriptException::class)
override fun eval(script: String): Any? {
return this.eval(script, context)
}
@Throws(ScriptException::class)
override fun eval(script: String, context: ScriptContext): Any? {
return this.eval(StringReader(script), context)
}
override fun getScriptContext(bindings: Bindings): ScriptContext {
val ctx = SimpleScriptContext()
val gs = getBindings(200)
if (gs != null) {
ctx.setBindings(gs, 200)
}
ctx.setBindings(bindings, 100)
ctx.reader = context.reader
ctx.writer = context.writer
ctx.errorWriter = context.errorWriter
return ctx
}
}

View File

@ -1,18 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
interface Bindings : MutableMap<String, Any?> {
override fun containsKey(key: String): Boolean
override operator fun get(key: String): Any?
override fun put(key: String, value: Any?): Any?
override fun putAll(from: Map<out String, *>)
override fun remove(key: String): Any?
}

View File

@ -1,15 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
import java.io.Reader
interface Compilable {
@Throws(ScriptException::class)
fun compile(script: Reader): CompiledScript
@Throws(ScriptException::class)
fun compile(script: String): CompiledScript
}

View File

@ -1,32 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
abstract class CompiledScript {
abstract fun getEngine(): ScriptEngine
@Throws(ScriptException::class)
abstract fun eval(context: ScriptContext): Any?
@Throws(ScriptException::class)
fun eval(bindings: Bindings?): Any? {
var ctxt = getEngine().context
if (bindings != null) {
val tempContext = SimpleScriptContext()
tempContext.setBindings(bindings, 100)
tempContext.setBindings(ctxt.getBindings(200), 200)
tempContext.writer = ctxt.writer
tempContext.reader = ctxt.reader
tempContext.errorWriter = ctxt.errorWriter
ctxt = tempContext
}
return this.eval(ctxt)
}
@Throws(ScriptException::class)
fun eval(): Any? {
return this.eval(getEngine().context)
}
}

View File

@ -1,16 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
interface Invocable {
fun <T> getInterface(clazz: Class<T>): T?
fun <T> getInterface(obj: Any?, paramClass: Class<T>): T?
@Throws(ScriptException::class, NoSuchMethodException::class)
fun invokeFunction(name: String, vararg args: Any): Any?
@Throws(ScriptException::class, NoSuchMethodException::class)
fun invokeMethod(obj: Any?, name: String, vararg args: Any): Any?
}

View File

@ -1,15 +0,0 @@
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)
}
}
}

View File

@ -1,37 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
import java.io.Reader
import java.io.Writer
interface ScriptContext {
var errorWriter: Writer
var reader: Reader
val scopes: List<Int>
var writer: Writer
fun getAttribute(name: String): Any?
fun getAttribute(name: String, scope: Int): Any?
fun getAttributesScope(name: String): Int
fun getBindings(scope: Int): Bindings?
fun removeAttribute(name: String, scope: Int): Any?
fun setAttribute(name: String, value: Any?, scope: Int)
fun setBindings(bindings: Bindings?, scope: Int)
companion object {
const val ENGINE_SCOPE = 100
const val GLOBAL_SCOPE = 200
}
}

View File

@ -1,53 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
import org.mozilla.javascript.Scriptable
import java.io.Reader
interface ScriptEngine {
var context: ScriptContext
fun createBindings(): Bindings?
@Throws(ScriptException::class)
fun eval(reader: Reader, scope: Scriptable): Any?
@Throws(ScriptException::class)
fun eval(script: String, scope: Scriptable): Any?
@Throws(ScriptException::class)
fun eval(reader: Reader): Any?
@Throws(ScriptException::class)
fun eval(reader: Reader, bindings: Bindings): Any?
@Throws(ScriptException::class)
fun eval(reader: Reader, context: ScriptContext): Any?
@Throws(ScriptException::class)
fun eval(script: String): Any?
@Throws(ScriptException::class)
fun eval(script: String, bindings: Bindings): Any?
@Throws(ScriptException::class)
fun eval(script: String, context: ScriptContext): Any?
fun getRuntimeScope(context: ScriptContext): Scriptable
fun getScriptContext(bindings: Bindings): ScriptContext
operator fun get(key: String): Any?
fun getBindings(scope: Int): Bindings?
fun put(key: String, value: Any?)
fun setBindings(bindings: Bindings?, scope: Int)
companion object {
const val FILENAME = "javax.script.filename"
}
}

View File

@ -1,54 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
class ScriptException : Exception {
var columnNumber: Int
private set
var fileName: String?
private set
var lineNumber: Int
private set
constructor(s: String?) : super(s) {
fileName = null
lineNumber = -1
columnNumber = -1
}
constructor(e: Exception?) : super(e) {
fileName = null
lineNumber = -1
columnNumber = -1
}
constructor(message: String?, fileName2: String?, lineNumber2: Int) : super(message) {
fileName = fileName2
lineNumber = lineNumber2
columnNumber = -1
}
constructor(message: String?, fileName2: String?, lineNumber2: Int, columnNumber2: Int) : super(
message
) {
fileName = fileName2
lineNumber = lineNumber2
columnNumber = columnNumber2
}
override val message: String
get() {
val ret = super.message
if (fileName == null) {
return ret!!
}
var ret2 = "$ret in $fileName"
if (lineNumber != -1) {
ret2 = "$ret2 at line number $lineNumber"
}
return if (columnNumber != -1) {
"$ret2 at column number $columnNumber"
} else ret2
}
}

View File

@ -1,54 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
class SimpleBindings @JvmOverloads constructor(
private val map: MutableMap<String, Any?> = HashMap()
) : Bindings {
override fun put(key: String, value: Any?): Any? {
return map.put(key, value)
}
override fun putAll(from: Map<out String, Any?>) {
map.putAll(from)
}
override fun clear() {
map.clear()
}
override fun containsKey(key: String): Boolean {
return map.containsKey(key)
}
override fun containsValue(value: Any?): Boolean {
return map.containsValue(value)
}
override val entries: MutableSet<MutableMap.MutableEntry<String, Any?>>
get() = map.entries
override operator fun get(key: String): Any? {
return map[key]
}
override fun isEmpty(): Boolean {
return map.isEmpty()
}
override val keys: MutableSet<String>
get() = map.keys
override fun remove(key: String): Any? {
return map.remove(key)
}
override val size: Int
get() = map.size
override val values: MutableCollection<Any?>
get() = map.values
}

View File

@ -1,113 +0,0 @@
/*
* Decompiled with CFR 0.152.
*/
package com.script
import java.io.InputStreamReader
import java.io.PrintWriter
import java.io.Reader
import java.io.Writer
import java.util.*
open class SimpleScriptContext : ScriptContext {
private var engineScope: Bindings = SimpleBindings()
override var errorWriter: Writer = PrintWriter(System.err, true)
private var globalScope: Bindings? = null
override var reader: Reader = InputStreamReader(System.`in`)
override var writer: Writer = PrintWriter(System.out, true)
override fun setBindings(bindings: Bindings?, scope: Int) {
when (scope) {
100 -> {
if (bindings == null) {
throw NullPointerException("Engine scope cannot be null.")
}
engineScope = bindings
return
}
200 -> {
globalScope = bindings
return
}
}
throw IllegalArgumentException("Invalid scope value.")
}
override fun getAttribute(name: String): Any? {
if (engineScope.containsKey(name)) {
return this.getAttribute(name, 100)
}
return if (globalScope?.containsKey(name) != true) {
null
} else this.getAttribute(name, 200)
}
override fun getAttribute(name: String, scope: Int): Any? {
when (scope) {
100 -> {
return engineScope[name]
}
200 -> {
return globalScope?.get(name)
}
}
throw IllegalArgumentException("Illegal scope value.")
}
override fun removeAttribute(name: String, scope: Int): Any? {
when (scope) {
100 -> {
return getBindings(100)?.remove(name)
}
200 -> {
return getBindings(200)?.remove(name)
}
}
throw IllegalArgumentException("Illegal scope value.")
}
override fun setAttribute(name: String, value: Any?, scope: Int) {
when (scope) {
100 -> {
engineScope[name] = value
return
}
200 -> {
globalScope?.put(name, value)
return
}
}
throw IllegalArgumentException("Illegal scope value.")
}
override fun getAttributesScope(name: String): Int {
if (engineScope.containsKey(name)) {
return 100
}
return if (globalScope?.containsKey(name) != true) {
-1
} else 200
}
override fun getBindings(scope: Int): Bindings? {
if (scope == 100) {
return engineScope
}
if (scope == 200) {
return globalScope
}
throw IllegalArgumentException("Illegal scope value.")
}
override val scopes: List<Int>
get() = Companion.scopes
companion object {
private var scopes: MutableList<Int> = ArrayList(2)
init {
scopes.add(100)
scopes.add(200)
scopes = Collections.unmodifiableList(scopes)
}
}
}

View File

@ -1,290 +0,0 @@
/*
* Copyright (c) 2005, 2006, 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 com.script.rhino
import com.script.ScriptContext
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
/**
* ExternalScriptable is an implementation of Scriptable
* backed by a JSR 223 ScriptContext instance.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
internal class ExternalScriptable @JvmOverloads constructor(
val context: ScriptContext,
private val indexedProps: MutableMap<Any, Any?> = HashMap()
) : Scriptable {
private var prototype: Scriptable? = null
private var parent: Scriptable? = null
override fun getClassName(): String {
return "Global"
}
@Synchronized
override fun get(name: String, start: Scriptable): Any? {
return if (name.isEmpty()) {
indexedProps.getOrElse(name) { Scriptable.NOT_FOUND }
} else {
synchronized(context) {
val scope = context.getAttributesScope(name)
return if (scope != -1) {
val value = context.getAttribute(name, scope)
Context.javaToJS(value, this)
} else {
Scriptable.NOT_FOUND
}
}
}
}
@Synchronized
override fun get(index: Int, start: Scriptable): Any? {
return indexedProps.getOrElse(index) { Scriptable.NOT_FOUND }
}
@Synchronized
override fun has(name: String, start: Scriptable): Boolean {
return if (name.isEmpty()) {
indexedProps.containsKey(name)
} else {
synchronized(context) { return context.getAttributesScope(name) != -1 }
}
}
@Synchronized
override fun has(index: Int, start: Scriptable): Boolean {
return indexedProps.containsKey(index)
}
override fun put(name: String, start: Scriptable, value: Any?) {
if (start === this) {
synchronized(this) {
if (name.isEmpty()) {
indexedProps.put(name, value)
} else {
synchronized(context) {
var scope = context.getAttributesScope(name)
if (scope == -1) {
scope = 100
}
context.setAttribute(name, jsToJava(value), scope)
}
}
}
} else {
start.put(name, start, value)
}
}
override fun put(index: Int, start: Scriptable, value: Any?) {
if (start === this) {
synchronized(this) { indexedProps.put(index, value) }
} else {
start.put(index, start, value)
}
}
@Synchronized
override fun delete(name: String) {
if (name.isEmpty()) {
indexedProps.remove(name)
} else {
synchronized(context) {
val scope = context.getAttributesScope(name)
if (scope != -1) {
context.removeAttribute(name, scope)
}
}
}
}
override fun delete(index: Int) {
indexedProps.remove(index)
}
override fun getPrototype(): Scriptable? {
return prototype
}
override fun setPrototype(prototype: Scriptable?) {
this.prototype = prototype
}
override fun getParentScope(): Scriptable? {
return parent
}
override fun setParentScope(parent: Scriptable?) {
this.parent = parent
}
@Synchronized
override fun getIds(): Array<Any> {
val keys = allKeys
val size = keys.size + indexedProps.size
val res = arrayOfNulls<Any>(size)
System.arraycopy(keys, 0, res, 0, keys.size)
var i = keys.size
var index: Any
val var5: Iterator<*> = indexedProps.keys.iterator()
while (var5.hasNext()) {
index = var5.next()!!
res[i++] = index
}
@Suppress("UNCHECKED_CAST")
return res as Array<Any>
}
override fun getDefaultValue(typeHint: Class<*>?): Any {
for (i in 0..1) {
val tryToString: Boolean =
if (typeHint == ScriptRuntime.StringClass) {
i == 0
} else {
i == 1
}
var methodName: String
var args: Array<Any?>
if (tryToString) {
methodName = "toString"
args = ScriptRuntime.emptyArgs
} else {
methodName = "valueOf"
args = arrayOfNulls(1)
val hint: String = when {
typeHint == null -> {
"undefined"
}
typeHint == ScriptRuntime.StringClass -> {
"string"
}
typeHint == ScriptRuntime.ScriptableClass -> {
"object"
}
typeHint == ScriptRuntime.FunctionClass -> {
"function"
}
typeHint != ScriptRuntime.BooleanClass && typeHint != java.lang.Boolean.TYPE -> {
if (typeHint != ScriptRuntime.NumberClass
&& typeHint != ScriptRuntime.ByteClass
&& typeHint != java.lang.Byte.TYPE
&& typeHint != ScriptRuntime.ShortClass
&& typeHint != java.lang.Short.TYPE
&& typeHint != ScriptRuntime.IntegerClass
&& typeHint != Integer.TYPE
&& typeHint != ScriptRuntime.FloatClass
&& typeHint != java.lang.Float.TYPE
&& typeHint != ScriptRuntime.DoubleClass
&& typeHint != java.lang.Double.TYPE
) {
throw Context.reportRuntimeError("Invalid JavaScript value of type $typeHint")
}
"number"
}
else -> {
"boolean"
}
}
args[0] = hint
}
var v = ScriptableObject.getProperty(this, methodName)
if (v is Function) {
val function = v
val cx = Context.enter()
v = try {
function.call(cx, function.parentScope, this, args)
} finally {
Context.exit()
}
if (v != null) {
if (v !is Scriptable) {
return v
}
if (typeHint == ScriptRuntime.ScriptableClass || typeHint == ScriptRuntime.FunctionClass) {
return v
}
if (tryToString && v is Wrapper) {
val u = (v as Wrapper).unwrap()
if (u is String) {
return u
}
}
}
}
}
val arg = if (typeHint == null) "undefined" else typeHint.name
throw Context.reportRuntimeError("找不到对象的默认值 $arg")
}
override fun hasInstance(instance: Scriptable): Boolean {
var proto = instance.prototype
while (proto != null) {
if (proto == this) {
return true
}
proto = proto.prototype
}
return false
}
private val allKeys: Array<String>
get() {
val list = ArrayList<String>()
synchronized(context) {
val iterator: Iterator<*> = context.scopes.iterator()
while (iterator.hasNext()) {
val scope = iterator.next() as Int
val bindings = context.getBindings(scope)
if (bindings != null) {
list.ensureCapacity(bindings.size)
val iterator1: Iterator<*> = bindings.keys.iterator()
while (iterator1.hasNext()) {
val key = iterator1.next() as String
list.add(key)
}
}
}
}
return list.toTypedArray()
}
private fun jsToJava(jsObj: Any?): Any? {
return if (jsObj is Wrapper) {
if (jsObj is NativeJavaClass) {
jsObj
} else {
val obj = jsObj.unwrap()
if (obj !is Number && obj !is String && obj !is Boolean && obj !is Char) obj else jsObj
}
} else {
jsObj
}
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) 2005, 2011, 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 com.script.rhino
import com.script.Invocable
import com.script.ScriptException
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import java.security.AccessControlContext
import java.security.AccessController
import java.security.PrivilegedExceptionAction
/**
* java.lang.reflect.Proxy based interface implementor. This is meant
* to be used to implement Invocable.getInterface.
*
* @author Mike Grogan
* @since 1.6
*/
@Suppress("UNUSED_PARAMETER")
open class InterfaceImplementor(private val engine: Invocable) {
@Throws(ScriptException::class)
fun <T> getInterface(obj: Any?, clazz: Class<T>?): T? {
return if (clazz != null && clazz.isInterface) {
if (!isImplemented(obj, clazz)) {
null
} else {
val accContext = AccessController.getContext()
clazz.cast(
Proxy.newProxyInstance(
clazz.classLoader,
arrayOf<Class<*>>(clazz),
InterfaceImplementorInvocationHandler(obj, accContext)
)
)
}
} else {
throw IllegalArgumentException("interface Class expected")
}
}
protected open fun isImplemented(obj: Any?, clazz: Class<*>): Boolean {
return true
}
@Throws(ScriptException::class)
protected open fun convertResult(method: Method?, res: Any?): Any? {
return res
}
@Throws(ScriptException::class)
protected fun convertArguments(method: Method?, args: Array<Any>): Array<Any> {
return args
}
private inner class InterfaceImplementorInvocationHandler(
private val obj: Any?,
private val accContext: AccessControlContext
) : InvocationHandler {
@Throws(Throwable::class)
override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any? {
val finalArgs = convertArguments(method, args)
val result = AccessController.doPrivileged(PrivilegedExceptionAction {
if (obj == null) engine.invokeFunction(method.name, *finalArgs)
else engine.invokeMethod(obj, method.name, *finalArgs)
}, accContext)
return convertResult(method, result)
}
}
}

View File

@ -1,307 +0,0 @@
/*
* 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 com.script.rhino
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
/**
* JSAdapter is java.lang.reflect.Proxy equivalent for JavaScript. JSAdapter
* calls specially named JavaScript methods on an adaptee object when property
* access is attempted on it.
*
* Example:
*
* var y = {
* __get__ : function (name) { ... }
* __has__ : function (name) { ... }
* __put__ : function (name, value) {...}
* __delete__ : function (name) { ... }
* __getIds__ : function () { ... }
* };
*
* var x = new JSAdapter(y);
*
* x.i; // calls y.__get__
* i in x; // calls y.__has__
* x.p = 10; // calls y.__put__
* delete x.p; // calls y.__delete__
* for (i in x) { print(i); } // calls y.__getIds__
*
* If a special JavaScript method is not found in the adaptee, then JSAdapter
* forwards the property access to the adaptee itself.
*
* JavaScript caller of adapter object is isolated from the fact that
* the property access/mutation/deletion are really calls to
* JavaScript methods on adaptee. Use cases include 'smart'
* properties, property access tracing/debugging, encaptulation with
* easy client access - in short JavaScript becomes more "Self" like.
*
* Note that Rhino already supports special properties like __proto__
* (to set, get prototype), __parent__ (to set, get parent scope). We
* follow the same double underscore nameing convention here. Similarly
* the name JSAdapter is derived from JavaAdapter -- which is a facility
* to extend, implement Java classes/interfaces by JavaScript.
*
* @author A. Sundararajan
* @since 1.6
*/
@Suppress("unused", "UNUSED_PARAMETER")
class JSAdapter private constructor(var adaptee: Scriptable) : Scriptable, Function {
private var prototype: Scriptable? = null
private var parent: Scriptable? = null
private var isPrototype = false
override fun getClassName(): String {
return "JSAdapter"
}
override fun get(name: String, start: Scriptable): Any {
val func = getAdapteeFunction(GET_PROP)
return if (func != null) {
this.call(func, arrayOf(name))
} else {
adaptee[name, adaptee]
}
}
override fun get(index: Int, start: Scriptable): Any {
val func = getAdapteeFunction(GET_PROP)
return if (func != null) {
this.call(func, arrayOf(index))
} else {
adaptee[index, adaptee]
}
}
override fun has(name: String, start: Scriptable): Boolean {
val func = getAdapteeFunction(HAS_PROP)
return if (func != null) {
val res = this.call(func, arrayOf(name))
Context.toBoolean(res)
} else {
adaptee.has(name, adaptee)
}
}
override fun has(index: Int, start: Scriptable): Boolean {
val func = getAdapteeFunction(HAS_PROP)
return if (func != null) {
val res = this.call(func, arrayOf(index))
Context.toBoolean(res)
} else {
adaptee.has(index, adaptee)
}
}
override fun put(name: String, start: Scriptable, value: Any) {
if (start === this) {
val func = getAdapteeFunction(PUT_PROP)
if (func != null) {
this.call(func, arrayOf(name, value))
} else {
adaptee.put(name, adaptee, value)
}
} else {
start.put(name, start, value)
}
}
override fun put(index: Int, start: Scriptable, value: Any) {
if (start === this) {
val func = getAdapteeFunction(PUT_PROP)
if (func != null) {
this.call(func, arrayOf(index, value))
} else {
adaptee.put(index, adaptee, value)
}
} else {
start.put(index, start, value)
}
}
override fun delete(name: String) {
val func = getAdapteeFunction(DEL_PROP)
if (func != null) {
this.call(func, arrayOf(name))
} else {
adaptee.delete(name)
}
}
override fun delete(index: Int) {
val func = getAdapteeFunction(DEL_PROP)
if (func != null) {
this.call(func, arrayOf(index))
} else {
adaptee.delete(index)
}
}
override fun getPrototype(): Scriptable? {
return prototype
}
override fun setPrototype(prototype: Scriptable?) {
this.prototype = prototype
}
override fun getParentScope(): Scriptable? {
return parent
}
override fun setParentScope(parent: Scriptable?) {
this.parent = parent
}
override fun getIds(): Array<Any?> {
val func = getAdapteeFunction(GET_PROPIDS)
return if (func == null) {
adaptee.ids
} else {
val val1 = this.call(func, arrayOfNulls(0))
val res: Array<Any?>
when (val1) {
is NativeArray -> {
res = arrayOfNulls(val1.length.toInt())
for (index in res.indices) {
res[index] = mapToId(val1[index, val1])
}
res
}
!is NativeJavaArray -> {
Context.emptyArgs
}
else -> {
val tmp = val1.unwrap()
if (tmp.javaClass == Array<Any>::class.java) {
val array = tmp as Array<*>
res = arrayOfNulls(array.size)
for (index in array.indices) {
res[index] = mapToId(array[index])
}
} else {
res = Context.emptyArgs
}
res
}
}
}
}
override fun hasInstance(scriptable: Scriptable): Boolean {
return if (scriptable is JSAdapter) {
true
} else {
var proto = scriptable.prototype
while (proto != null) {
if (proto == this) {
return true
}
proto = proto.prototype
}
false
}
}
override fun getDefaultValue(hint: Class<*>?): Any {
return adaptee.getDefaultValue(hint)
}
@Throws(RhinoException::class)
override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable, args: Array<Any>): Any {
return if (isPrototype) {
construct(cx, scope, args)
} else {
val tmp = adaptee
if (tmp is Function) {
tmp.call(cx, scope, tmp, args)
} else {
throw Context.reportRuntimeError("TypeError: not a function")
}
}
}
@Throws(RhinoException::class)
override fun construct(cx: Context, scope: Scriptable, args: Array<Any>): Scriptable {
val tmp: Scriptable?
return if (isPrototype) {
tmp = ScriptableObject.getTopLevelScope(scope)
if (args.isNotEmpty()) {
JSAdapter(Context.toObject(args[0], tmp))
} else {
throw Context.reportRuntimeError("JSAdapter requires adaptee")
}
} else {
tmp = adaptee
if (tmp is Function) {
tmp.construct(cx, scope, args)
} else {
throw Context.reportRuntimeError("TypeError: not a constructor")
}
}
}
private fun mapToId(tmp: Any?): Any {
return if (tmp is Double) tmp.toInt() else Context.toString(tmp)
}
private fun getAdapteeFunction(name: String): Function? {
val o = ScriptableObject.getProperty(adaptee, name)
return o as? Function
}
private fun call(func: Function, args: Array<Any?>): Any {
val cx = Context.getCurrentContext()
val thisObj = adaptee
val scope = func.parentScope
return try {
func.call(cx, scope, thisObj, args)
} catch (re: RhinoException) {
throw Context.reportRuntimeError(re.message)
}
}
companion object {
private const val GET_PROP = "__get__"
private const val HAS_PROP = "__has__"
private const val PUT_PROP = "__put__"
private const val DEL_PROP = "__delete__"
private const val GET_PROPIDS = "__getIds__"
@Throws(RhinoException::class)
fun init(cx: Context, scope: Scriptable, sealed: Boolean) {
val obj = JSAdapter(cx.newObject(scope))
obj.parentScope = scope
obj.setPrototype(getFunctionPrototype(scope))
obj.isPrototype = true
ScriptableObject.defineProperty(scope, "JSAdapter", obj, 2)
}
private fun getFunctionPrototype(scope: Scriptable): Scriptable {
return ScriptableObject.getFunctionPrototype(scope)
}
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (c) 2005, 2006, 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 com.script.rhino
import com.script.Invocable
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
/**
* This class implements Rhino-like JavaAdapter to help implement a Java
* interface in JavaScript. We support this using Invocable.getInterface.
* Using this JavaAdapter, script author could write:
*
*
* var r = new java.lang.Runnable() {
* run: function() { script... }
* };
*
*
* r.run();
* new java.lang.Thread(r).start();
*
*
* Note that Rhino's JavaAdapter support allows extending a Java class and/or
* implementing one or more interfaces. This JavaAdapter implementation does
* not support these.
*
* @author A. Sundararajan
* @since 1.6
*/
@Suppress("UNUSED_PARAMETER")
internal class JavaAdapter private constructor(private val engine: Invocable) : ScriptableObject(),
Function {
override fun getClassName(): String {
return "JavaAdapter"
}
@Throws(RhinoException::class)
override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable, args: Array<Any>): Any {
return construct(cx, scope, args)
}
@Throws(RhinoException::class)
override fun construct(cx: Context, scope: Scriptable, args: Array<Any>): Scriptable {
return if (args.size == 2) {
var clazz: Class<*>? = null
val obj = args[0]
if (obj is Wrapper) {
val o = obj.unwrap()
if (o is Class<*> && o.isInterface) {
clazz = o
}
} else if (obj is Class<*> && obj.isInterface) {
clazz = obj
}
if (clazz == null) {
throw Context.reportRuntimeError("JavaAdapter: first arg should be interface Class")
} else {
val topLevel = getTopLevelScope(scope)
Context.toObject(
engine.getInterface(args[1], clazz),
topLevel
)
}
} else {
throw Context.reportRuntimeError("JavaAdapter requires two arguments")
}
}
companion object {
@JvmStatic
@Throws(RhinoException::class)
fun init(cx: Context, scope: Scriptable, sealed: Boolean) {
val topLevel = scope as RhinoTopLevel
val engine: Invocable = topLevel.scriptEngine
val obj = JavaAdapter(engine)
obj.parentScope = scope
obj.prototype = getFunctionPrototype(scope)
putProperty(topLevel, "JavaAdapter", obj)
}
}
}

View File

@ -1,72 +0,0 @@
/*
* 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 com.script.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.Class"] = true
protectedClasses["java.lang.ClassLoader"] = true
protectedClasses["java.lang.Runtime"] = true
protectedClasses["java.io.File"] = true
protectedClasses["java.security.AccessController"] = true
protectedClasses["java.nio.file.Paths"] = true
protectedClasses["java.nio.file.Files"] = true
protectedClasses["io.legado.app.data.AppDatabaseKt"] = true
protectedClasses["io.legado.app.utils.ContextExtensionsKt"] = true
protectedClasses["android.content.Intent"] = true
protectedClasses["androidx.core.content.FileProvider"] = true
protectedClasses["android.provider.Settings"] = true
protectedClasses["androidx.sqlite.db"] = 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
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2005, 2006, 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 com.script.rhino
import com.script.CompiledScript
import com.script.ScriptContext
import com.script.ScriptEngine
import com.script.ScriptException
import org.mozilla.javascript.*
/**
* Represents compiled JavaScript code.
*
* @author Mike Grogan
* @since 1.6
*/
internal class RhinoCompiledScript(
private val engine: RhinoScriptEngine,
private val script: Script
) : CompiledScript() {
override fun getEngine(): ScriptEngine {
return engine
}
@Throws(ScriptException::class)
override fun eval(context: ScriptContext): Any? {
val cx = Context.enter()
val result: Any?
try {
val scope = engine.getRuntimeScope(context)
val ret = script.exec(cx, scope)
result = engine.unwrapReturnValue(ret)
} catch (re: RhinoException) {
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
val msg: String = if (re is JavaScriptException) {
re.value.toString()
} else {
re.toString()
}
val se = ScriptException(msg, re.sourceName(), line)
se.initCause(re)
throw se
} finally {
Context.exit()
}
return result
}
}

View File

@ -1,310 +0,0 @@
/*
* Copyright (c) 2005, 2011, 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 com.script.rhino
import com.script.*
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
import java.io.IOException
import java.io.Reader
import java.io.StringReader
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")
object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
var accessContext: AccessControlContext? = null
private var topLevel: RhinoTopLevel? = null
private val indexedProps: MutableMap<Any, Any?>
private val implementor: InterfaceImplementor
@Throws(ScriptException::class)
override fun eval(reader: Reader, scope: Scriptable): Any? {
val cx = Context.enter()
val ret: Any?
try {
var filename = this["javax.script.filename"] as? String
filename = filename ?: "<Unknown source>"
ret = cx.evaluateReader(scope, reader, filename, 1, null)
} catch (re: RhinoException) {
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
val msg: String = if (re is JavaScriptException) {
re.value.toString()
} else {
re.toString()
}
val se = ScriptException(msg, re.sourceName(), line)
se.initCause(re)
throw se
} catch (var14: IOException) {
throw ScriptException(var14)
} finally {
Context.exit()
}
return unwrapReturnValue(ret)
}
override fun createBindings(): Bindings {
return SimpleBindings()
}
@Throws(ScriptException::class, NoSuchMethodException::class)
override fun invokeFunction(name: String, vararg args: Any): Any? {
return this.invoke(null, name, *args)
}
@Throws(ScriptException::class, NoSuchMethodException::class)
override fun invokeMethod(obj: Any?, name: String, vararg args: Any): Any? {
return if (obj == null) {
throw IllegalArgumentException("脚本对象不能为空")
} else {
this.invoke(obj, name, *args)
}
}
@Suppress("UNCHECKED_CAST")
@Throws(ScriptException::class, NoSuchMethodException::class)
private operator fun invoke(thiz: Any?, name: String?, vararg args: Any?): Any? {
var thiz1 = thiz
val cx = Context.enter()
val var11: Any?
try {
if (name == null) {
throw NullPointerException("方法名为空")
}
if (thiz1 != null && thiz1 !is Scriptable) {
thiz1 = Context.toObject(thiz1, topLevel)
}
val engineScope = getRuntimeScope(context)
val localScope = if (thiz1 != null) thiz1 as Scriptable else engineScope
val obj = ScriptableObject.getProperty(localScope, name) as? Function
?: throw NoSuchMethodException("no such method: $name")
var scope = obj.parentScope
if (scope == null) {
scope = engineScope
}
val result = obj.call(cx, scope, localScope, wrapArguments(args as? Array<Any?>))
var11 = unwrapReturnValue(result)
} catch (re: RhinoException) {
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
val se = ScriptException(re.toString(), re.sourceName(), line)
se.initCause(re)
throw se
} finally {
Context.exit()
}
return var11
}
override fun <T> getInterface(clazz: Class<T>): T? {
return try {
implementor.getInterface(null, clazz)
} catch (var3: ScriptException) {
null
}
}
override fun <T> getInterface(obj: Any?, paramClass: Class<T>): T? {
return if (obj == null) {
throw IllegalArgumentException("脚本对象不能为空")
} else {
try {
implementor.getInterface(obj, paramClass)
} catch (var4: ScriptException) {
null
}
}
}
override fun getRuntimeScope(context: ScriptContext): Scriptable {
val newScope: Scriptable = ExternalScriptable(context, indexedProps)
newScope.prototype = topLevel
newScope.put("context", newScope, context)
return newScope
}
@Throws(ScriptException::class)
override fun compile(script: String): CompiledScript {
return this.compile(StringReader(script) as Reader)
}
@Throws(ScriptException::class)
override fun compile(script: Reader): CompiledScript {
val cx = Context.enter()
val ret: RhinoCompiledScript
try {
var fileName = this["javax.script.filename"] as? String
if (fileName == null) {
fileName = "<Unknown Source>"
}
val scr = cx.compileReader(script, fileName, 1, null)
ret = RhinoCompiledScript(this, scr)
} catch (var9: Exception) {
throw ScriptException(var9)
} finally {
Context.exit()
}
return ret
}
fun wrapArguments(args: Array<Any?>?): Array<Any?> {
return if (args == null) {
Context.emptyArgs
} else {
val res = arrayOfNulls<Any>(args.size)
for (i in res.indices) {
res[i] = Context.javaToJS(args[i], topLevel)
}
res
}
}
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 : 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())
} catch (var6: AccessControlException) {
accessContext = AccessController.getContext()
}
}
val cx = Context.enter()
try {
topLevel = RhinoTopLevel(cx, this)
} finally {
Context.exit()
}
indexedProps = HashMap()
implementor = object : InterfaceImplementor(this) {
override fun isImplemented(obj: Any?, clazz: Class<*>): Boolean {
var obj1 = obj
return try {
if (obj1 != null && obj1 !is Scriptable) {
obj1 = Context.toObject(obj1, topLevel)
}
val engineScope = getRuntimeScope(context)
val localScope = if (obj1 != null) obj1 as Scriptable else engineScope
val methods = clazz.methods
val methodsSize = methods.size
for (index in 0 until methodsSize) {
val method = methods[index]
if (method.declaringClass != Any::class.java) {
if (ScriptableObject.getProperty(
localScope,
method.name
) !is Function
) {
return false
}
}
}
true
} finally {
Context.exit()
}
}
override fun convertResult(method: Method?, res: Any?): Any? {
method ?: return null
val desiredType = method.returnType
if (desiredType == Void.TYPE) return null
return Context.jsToJava(res, desiredType)
}
}
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright (c) 2005, 2010, 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 com.script.rhino
import com.script.Bindings
import com.script.ScriptContext
import com.script.SimpleScriptContext
import org.mozilla.javascript.*
import org.mozilla.javascript.Function
import java.security.AccessControlContext
/**
* This class serves as top level scope for Rhino. This class adds
* 3 top level functions (bindings, scope, sync) and two constructors
* (JSAdapter, JavaAdapter).
*
* @author A. Sundararajan
* @since 1.6
*/
@Suppress("UNUSED_PARAMETER", "unused")
class RhinoTopLevel(cx: Context, val scriptEngine: RhinoScriptEngine) :
ImporterTopLevel(cx, System.getSecurityManager() != null) {
init {
LazilyLoadedCtor(this, "JSAdapter", "com.script.rhino.JSAdapter", false)
JavaAdapter.init(cx, this, false)
val names = arrayOf("bindings", "scope", "sync")
defineFunctionProperties(names, RhinoTopLevel::class.java, 2)
}
val accessContext: AccessControlContext?
get() = scriptEngine.accessContext
companion object {
@JvmStatic
fun bindings(
cx: Context,
thisObj: Scriptable?,
args: Array<Any?>,
funObj: Function?
): Any {
if (args.size == 1) {
var arg = args[0]
if (arg is Wrapper) {
arg = arg.unwrap()
}
if (arg is ExternalScriptable) {
val ctx = arg.context
val bind = ctx.getBindings(100)
return Context.javaToJS(bind, getTopLevelScope(thisObj))
}
}
return Context.getUndefinedValue()
}
@JvmStatic
fun scope(cx: Context, thisObj: Scriptable?, args: Array<Any?>, funObj: Function?): Any {
if (args.size == 1) {
var arg = args[0]
if (arg is Wrapper) {
arg = arg.unwrap()
}
if (arg is Bindings) {
val ctx: ScriptContext = SimpleScriptContext()
ctx.setBindings(arg as Bindings?, 100)
val res: Scriptable = cx.initSafeStandardObjects()
res.prototype = getObjectPrototype(thisObj)
res.parentScope = getTopLevelScope(thisObj)
return res
}
}
return Context.getUndefinedValue()
}
@JvmStatic
fun sync(cx: Context, thisObj: Scriptable?, args: Array<Any?>, funObj: Function?): Any {
return if (args.size == 1 && args[0] is Function) {
Synchronizer(args[0] as Function?)
} else {
throw Context.reportRuntimeError("wrong argument(s) for sync")
}
}
}
}

View File

@ -1,118 +0,0 @@
/*
* Copyright (c) 2005, 2006, 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 com.script.rhino
import org.mozilla.javascript.Context
import org.mozilla.javascript.NativeJavaObject
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.WrapFactory
import java.lang.reflect.Member
import java.lang.reflect.Modifier
/**
* This wrap factory is used for security reasons. JSR 223 script
* engine interface and JavaScript engine classes are run as bootstrap
* classes. For example, java.lang.Class.forName method (when called without
* class loader) uses caller's class loader. This may be exploited by script
* authors to access classes otherwise not accessible. For example,
* classes in sun.* namespace are normally not accessible to untrusted
* code and hence should not be accessible to JavaScript run from
* untrusted code.
*
* @author A. Sundararajan
* @since 1.6
*/
object RhinoWrapFactory : WrapFactory() {
override fun wrapAsJavaObject(
cx: Context,
scope: Scriptable?,
javaObject: Any,
staticType: Class<*>?
): Scriptable? {
scope?.delete("Packages")
val sm = System.getSecurityManager()
val classShutter = RhinoClassShutter
return if (javaObject is ClassLoader) {
sm?.checkPermission(RuntimePermission("getClassLoader"))
super.wrapAsJavaObject(cx, scope, javaObject, staticType)
} else {
var name: String? = null
if (javaObject is Class<*>) {
name = javaObject.name
} else if (javaObject is Member) {
if (sm != null && !Modifier.isPublic(javaObject.modifiers)) {
return null
}
name = javaObject.declaringClass.name
}
if (name != null) {
if (!classShutter.visibleToScripts(name)) null else super.wrapAsJavaObject(
cx,
scope,
javaObject,
staticType
)
} else {
var dynamicType: Class<*>? = javaObject.javaClass
name = dynamicType!!.name
if (classShutter.visibleToScripts(name)) {
super.wrapAsJavaObject(cx, scope, javaObject, staticType)
} else {
var type: Class<*>? = null
if (staticType != null && staticType.isInterface) {
type = staticType
} else {
while (dynamicType != null) {
dynamicType = dynamicType.superclass
name = dynamicType.name
if (classShutter.visibleToScripts(name)) {
type = dynamicType
break
}
}
assert(type != null) { "java.lang.Object 不可访问" }
}
RhinoJavaObject(scope, javaObject, type)
}
}
}
}
private class RhinoJavaObject(
scope: Scriptable?,
obj: Any?,
type: Class<*>?
) : NativeJavaObject(scope, null, type) {
init {
javaObject = obj
}
override fun get(name: String, start: Scriptable): Any {
return if (name != "getClass" && name != "exec") super.get(name, start) else NOT_FOUND
}
}
}

View File

@ -30,5 +30,4 @@ rootProject.name = 'legado'
include ':app' include ':app'
include ':modules:book' include ':modules:book'
include ':modules:rhino1.7.3' include ':modules:rhino1.7.3'
include ':modules:rhino1.7.4'