From 6ec6f69be2863056c1f10c56406e5a72f2e184cb Mon Sep 17 00:00:00 2001 From: Raphael Jolly Date: Fri, 22 Mar 2013 20:17:14 +0100 Subject: Bypass determination of protection domain when resource is not in a jar --- .../scala/tools/nsc/util/AbstractFileClassLoader.scala | 10 ++++++---- src/reflect/scala/reflect/io/ZipArchive.scala | 6 +++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala index e4f879560c..b204c39e9c 100644 --- a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala +++ b/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala @@ -8,7 +8,6 @@ package util import scala.tools.nsc.io.AbstractFile import java.security.cert.Certificate import java.security.{ ProtectionDomain, CodeSource } -import util.ScalaClassLoader import java.net.{ URL, URLConnection, URLStreamHandler } import scala.collection.{ mutable, immutable } @@ -91,10 +90,13 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) lazy val protectionDomain = { val cl = Thread.currentThread().getContextClassLoader() val resource = cl.getResource("scala/runtime/package.class") - if (resource == null) null else { + if (resource == null || resource.getProtocol != "jar") null else { val s = resource.getPath - val path = s.substring(0, s.lastIndexOf('!')) - new ProtectionDomain(new CodeSource(new URL(path), null.asInstanceOf[Array[Certificate]]), null, this, null) + val n = s.lastIndexOf('!') + if (n < 0) null else { + val path = s.substring(0, n) + new ProtectionDomain(new CodeSource(new URL(path), null.asInstanceOf[Array[Certificate]]), null, this, null) + } } } diff --git a/src/reflect/scala/reflect/io/ZipArchive.scala b/src/reflect/scala/reflect/io/ZipArchive.scala index 1342fde3c5..11d04538e9 100644 --- a/src/reflect/scala/reflect/io/ZipArchive.scala +++ b/src/reflect/scala/reflect/io/ZipArchive.scala @@ -259,7 +259,11 @@ final class ManifestResources(val url: URL) extends ZipArchive(null) { } def name = path - def path: String = url.getPath() match { case s => s.substring(0, s.lastIndexOf('!')) } + def path: String = { + val s = url.getPath + val n = s.lastIndexOf('!') + s.substring(0, n) + } def input = url.openStream() def lastModified = try url.openConnection().getLastModified() -- cgit v1.2.3 From 6c48941f0961a17647a6c95022d13fef3ab1f956 Mon Sep 17 00:00:00 2001 From: Raphael Jolly Date: Fri, 22 Mar 2013 20:19:17 +0100 Subject: The script engine is given a better binding mechanism and reflexive access Better binding mecanism : formerly done through the default SimpleBindings shipped with the API, it now goes through a custom IBindings class which uses the bind method of the interpreter instead of simply making the bindings available as a Map. Reflexive access : the script engine is made available to itself through a bound variable "engine" of type javax.script.ScriptEngine. This will allow "variable injection" i.e. programmatic redefinition of variables, among others. --- build.xml | 7 ++++ .../scala/tools/nsc/interpreter/IBindings.java | 45 ++++++++++++++++++++++ src/repl/scala/tools/nsc/interpreter/IMain.scala | 20 ++++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/repl/scala/tools/nsc/interpreter/IBindings.java diff --git a/build.xml b/build.xml index 8294f17d33..ce150b125d 100644 --- a/build.xml +++ b/build.xml @@ -1103,6 +1103,13 @@ QUICK BUILD (QUICK) + + + implements Bindings { + public Set> entrySet() { + return new AbstractSet>() { + public int size() { + return 0; + } + + public Iterator> iterator() { + return new Iterator>() { + public boolean hasNext() { + return false; + } + + public Map.Entry next() { + throw new NoSuchElementException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public boolean add(Map.Entry e) { + IBindings.this.put(e.getKey(), e.getValue()); + return true; + } + }; + } +} diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index c92777c13e..d2b6cdd7f0 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -21,7 +21,7 @@ import scala.tools.nsc.util.Exceptional.unwrap import scala.collection.{ mutable, immutable } import scala.reflect.BeanProperty import scala.util.Properties.versionString -import javax.script.{AbstractScriptEngine, Bindings, ScriptContext, ScriptEngine, ScriptEngineFactory, ScriptException, SimpleBindings, CompiledScript, Compilable} +import javax.script.{AbstractScriptEngine, Bindings, ScriptContext, ScriptEngine, ScriptEngineFactory, ScriptException, CompiledScript, Compilable} import java.io.{ StringWriter, Reader } import java.util.Arrays import IMain._ @@ -62,9 +62,10 @@ import StdReplTags._ * @author Moez A. Abdel-Gawad * @author Lex Spoon */ -class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Settings, protected val out: JPrintWriter) extends AbstractScriptEngine(new SimpleBindings) with Compilable with Imports { +class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Settings, protected val out: JPrintWriter) extends AbstractScriptEngine with Compilable with Imports { imain => + setBindings(createBindings, ScriptContext.ENGINE_SCOPE) object replOutput extends ReplOutput(settings.Yreploutdir) { } @deprecated("Use replOutput.dir instead", "2.11.0") @@ -554,7 +555,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set @throws(classOf[ScriptException]) def compile(script: String): CompiledScript = { if (!bound) { - quietBind("bindings", getBindings(ScriptContext.ENGINE_SCOPE)) + quietBind("engine", this.asInstanceOf[ScriptEngine]) bound = true } val cat = code + script @@ -969,7 +970,18 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set override def toString = "Request(line=%s, %s trees)".format(line, trees.size) } - def createBindings: Bindings = new SimpleBindings + def createBindings: Bindings = new IBindings { + override def put(name: String, value: Object): Object = { + val n = name.indexOf(":") + val p: NamedParam = if (n < 0) (name, value) else { + val nme = name.substring(0, n).trim + val tpe = name.substring(n + 1).trim + NamedParamClass(nme, tpe, value) + } + if (!p.name.startsWith("javax.script")) bind(p) + null + } + } @throws(classOf[ScriptException]) def eval(script: String, context: ScriptContext): Object = compile(script).eval(context) -- cgit v1.2.3