-
-
Save nlinker/1520472 to your computer and use it in GitHub Desktop.
Sandboxed Rhino, Scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#! scalac -classpath js.jar sketch.scala && java -classpath .:/opt/local/share/scala/lib/scala-library.jar:js.jar Main # | |
// http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/ | |
import java.lang.System | |
import org.mozilla.javascript._ | |
class SandboxNativeJavaObject (scope: Scriptable, javaObject: Object, staticType: Class[_]) | |
extends NativeJavaObject(scope, javaObject, staticType) { | |
override def get (name: String, start: Scriptable):Object = null | |
} | |
class SandboxWrapFactory extends WrapFactory { | |
override def wrapAsJavaObject (context: Context, scope: Scriptable, javaObject: Object, staticType: Class[_]):Scriptable = { | |
new SandboxNativeJavaObject(scope, javaObject, staticType); | |
} | |
} | |
class SandboxContext extends Context { | |
var startTime:Long = 0; | |
} | |
class SandboxContextFactory extends ContextFactory { | |
override def makeContext ():Context = { | |
val ret = new SandboxContext() | |
ret.setInstructionObserverThreshold(1000) | |
ret.setWrapFactory(new SandboxWrapFactory()) | |
ret | |
} | |
override def observeInstructionCount (context: Context, instructionCount: Int):Unit = { | |
val ctx = context.asInstanceOf[SandboxContext]; | |
val current = System.currentTimeMillis() | |
if (current >= ctx.startTime + 1000) { | |
throw new Error(); | |
} | |
} | |
override def doTopCall (callable: Callable, context: Context, scope: Scriptable, thisObject: Scriptable, args: Array[Object]):Object = { | |
val ctx = context.asInstanceOf[SandboxContext] | |
ctx.startTime = System.currentTimeMillis() | |
super.doTopCall(callable, ctx, scope, thisObject, args) | |
} | |
} | |
object Main extends Application { | |
ContextFactory.initGlobal(new SandboxContextFactory()); | |
val ctx = Context.enter() | |
ctx.setLanguageVersion(Context.VERSION_1_7) | |
// Java のクラスを一切エクスポートしない | |
ctx.setClassShutter(new ClassShutter() { | |
def visibleToScripts(fullClassName: String) = false; | |
}) | |
// ctx.setSecurityController(new SecurityController() { | |
// }) | |
try { | |
val scope = ctx.initStandardObjects() | |
ctx.evaluateString( | |
scope, | |
""" | |
Global = (function () { return this })(); | |
""", | |
"<init>", | |
1, | |
null | |
) | |
// JSON に変換してセットがいい | |
println("running") | |
val result = ctx.evaluateString( | |
scope, | |
""" | |
//=> must make error | |
// java.lang.System.println('foo') | |
// must timeout | |
for (;;) ; | |
""", | |
"<run>", | |
1, | |
null | |
) | |
println( Context.toString(result) ) | |
} catch { | |
case e: EcmaError => println(e) | |
} finally { | |
Context.exit() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment