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

View File

@ -37,36 +37,39 @@ import org.mozilla.javascript.ClassShutter
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
hashSetOf(
"dalvik.system",
"org.mozilla.javascript",
"java.lang.Class",
"java.lang.ClassLoader",
"java.net.URLClassLoader",
"cn.hutool.core.lang.JarClassLoader",
"java.lang.Runtime",
"java.io.File",
"java.security.AccessController",
"java.nio.file.Paths",
"java.nio.file.Files",
"io.legado.app.data.AppDatabaseKt",
"io.legado.app.utils.ContextExtensionsKt",
"android.content.Intent",
"androidx.core.content.FileProvider",
"android.provider.Settings",
"androidx.sqlite.db",
)
}
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 (var5: SecurityException) {
if (!protectedClasses.contains(fullClassName)) {
var className = fullClassName
while (className.contains(".")) {
className = className.substringBeforeLast(".")
if (protectedClasses.contains(className)) {
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 ':modules:book'
include ':modules:rhino1.7.3'
include ':modules:rhino1.7.4'
include ':modules:rhino1.7.3'