mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Resolving bug 236193: require enetered Context for compilation
This commit is contained in:
parent
cb4be12ceb
commit
58db1d9fd5
@ -2070,6 +2070,11 @@ public class Context
|
||||
boolean fromEval)
|
||||
throws IOException
|
||||
{
|
||||
if (securityDomain != null && securityController == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"securityDomain should be null if setSecurityController() was never called");
|
||||
}
|
||||
|
||||
// One of sourceReader or sourceString has to be null
|
||||
if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug();
|
||||
// scope should be given if and only if compiling function
|
||||
@ -2096,19 +2101,12 @@ public class Context
|
||||
int syntaxErrorCount = compilerEnv.getSyntaxErrorCount();
|
||||
if (syntaxErrorCount == 0) {
|
||||
Interpreter compiler = createCompiler();
|
||||
if (securityController != null) {
|
||||
securityDomain = securityController.
|
||||
getDynamicSecurityDomain(securityDomain);
|
||||
} else {
|
||||
securityDomain = null;
|
||||
}
|
||||
|
||||
String encodedSource = p.getEncodedSource();
|
||||
|
||||
Object result = compiler.compile(this, scope, compilerEnv,
|
||||
Object result = compiler.compile(scope, compilerEnv,
|
||||
tree, encodedSource,
|
||||
returnFunction,
|
||||
securityController,
|
||||
securityDomain);
|
||||
syntaxErrorCount = compilerEnv.getSyntaxErrorCount();
|
||||
if (syntaxErrorCount == 0) {
|
||||
|
@ -110,13 +110,12 @@ public class Interpreter
|
||||
// Last icode
|
||||
END_ICODE = BASE_ICODE + 30;
|
||||
|
||||
public Object compile(Context cx, Scriptable scope,
|
||||
public Object compile(Scriptable scope,
|
||||
CompilerEnvirons compilerEnv,
|
||||
ScriptOrFnNode tree,
|
||||
String encodedSource,
|
||||
boolean returnFunction,
|
||||
SecurityController securityController,
|
||||
Object securityDomain)
|
||||
Object staticSecurityDomain)
|
||||
{
|
||||
this.compilerEnv = compilerEnv;
|
||||
(new NodeTransformer(compilerEnv)).transform(tree);
|
||||
@ -129,17 +128,30 @@ public class Interpreter
|
||||
tree = tree.getFunctionNode(0);
|
||||
}
|
||||
|
||||
Context cx = Context.getContext();
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
Object dynamicDomain;
|
||||
if (sc != null) {
|
||||
dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain);
|
||||
} else {
|
||||
if (staticSecurityDomain != null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
dynamicDomain = null;
|
||||
}
|
||||
|
||||
scriptOrFn = tree;
|
||||
itsData = new InterpreterData(securityDomain,
|
||||
compilerEnv.getLanguageVersion());
|
||||
itsData.itsSourceFile = scriptOrFn.getSourceName();
|
||||
itsData.encodedSource = encodedSource;
|
||||
itsData = new InterpreterData(sc, dynamicDomain,
|
||||
compilerEnv.getLanguageVersion(),
|
||||
scriptOrFn.getSourceName(),
|
||||
encodedSource);
|
||||
itsData.topLevel = true;
|
||||
|
||||
if (tree instanceof FunctionNode) {
|
||||
generateFunctionICode(cx);
|
||||
generateFunctionICode();
|
||||
return createFunction(cx, scope, itsData, false);
|
||||
} else {
|
||||
generateICodeFromTree(cx, scriptOrFn);
|
||||
generateICodeFromTree(scriptOrFn);
|
||||
itsData.itsFromEvalCode = compilerEnv.isFromEval();
|
||||
return new InterpretedScript(itsData);
|
||||
}
|
||||
@ -169,7 +181,7 @@ public class Interpreter
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFunctionICode(Context cx)
|
||||
private void generateFunctionICode()
|
||||
{
|
||||
FunctionNode theFunction = (FunctionNode)scriptOrFn;
|
||||
|
||||
@ -186,14 +198,14 @@ public class Interpreter
|
||||
}
|
||||
}
|
||||
|
||||
generateICodeFromTree(cx, theFunction.getLastChild());
|
||||
generateICodeFromTree(theFunction.getLastChild());
|
||||
}
|
||||
|
||||
private void generateICodeFromTree(Context cx, Node tree)
|
||||
private void generateICodeFromTree(Node tree)
|
||||
{
|
||||
generateNestedFunctions(cx);
|
||||
generateNestedFunctions();
|
||||
|
||||
generateRegExpLiterals(cx);
|
||||
generateRegExpLiterals();
|
||||
|
||||
int theICodeTop = 0;
|
||||
theICodeTop = generateICode(tree, theICodeTop);
|
||||
@ -260,7 +272,7 @@ public class Interpreter
|
||||
if (Token.printICode) dumpICode(itsData);
|
||||
}
|
||||
|
||||
private void generateNestedFunctions(Context cx)
|
||||
private void generateNestedFunctions()
|
||||
{
|
||||
int functionCount = scriptOrFn.getFunctionCount();
|
||||
if (functionCount == 0) return;
|
||||
@ -271,24 +283,21 @@ public class Interpreter
|
||||
Interpreter jsi = new Interpreter();
|
||||
jsi.compilerEnv = compilerEnv;
|
||||
jsi.scriptOrFn = def;
|
||||
jsi.itsData = new InterpreterData(itsData.securityDomain,
|
||||
itsData.languageVersion);
|
||||
jsi.itsData.parentData = itsData;
|
||||
jsi.itsData.itsSourceFile = itsData.itsSourceFile;
|
||||
jsi.itsData.encodedSource = itsData.encodedSource;
|
||||
jsi.itsData = new InterpreterData(itsData);
|
||||
jsi.itsData.itsCheckThis = def.getCheckThis();
|
||||
jsi.itsInFunctionFlag = true;
|
||||
jsi.generateFunctionICode(cx);
|
||||
jsi.generateFunctionICode();
|
||||
array[i] = jsi.itsData;
|
||||
}
|
||||
itsData.itsNestedFunctions = array;
|
||||
}
|
||||
|
||||
private void generateRegExpLiterals(Context cx)
|
||||
private void generateRegExpLiterals()
|
||||
{
|
||||
int N = scriptOrFn.getRegexpCount();
|
||||
if (N == 0) return;
|
||||
|
||||
Context cx = Context.getContext();
|
||||
RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
|
||||
Object[] array = new Object[N];
|
||||
for (int i = 0; i != N; i++) {
|
||||
@ -1857,8 +1866,7 @@ public class Interpreter
|
||||
if (argsDbl != null) {
|
||||
args = getArgsArray(args, argsDbl, argShift, argCount);
|
||||
}
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
|
||||
SecurityController sc = idata.securityController;
|
||||
Object savedDomain = cx.interpreterSecurityDomain;
|
||||
cx.interpreterSecurityDomain = idata.securityDomain;
|
||||
try {
|
||||
|
@ -49,17 +49,42 @@ final class InterpreterData implements Serializable, DebuggableScript
|
||||
static final int INITIAL_STRINGTABLE_SIZE = 64;
|
||||
static final int INITIAL_NUMBERTABLE_SIZE = 64;
|
||||
|
||||
InterpreterData(Object securityDomain, int languageVersion)
|
||||
InterpreterData(SecurityController securityController,
|
||||
Object securityDomain,
|
||||
int languageVersion,
|
||||
String sourceFile, String encodedSource)
|
||||
{
|
||||
this.securityController = securityController;
|
||||
this.securityDomain = securityDomain;
|
||||
this.languageVersion = languageVersion;
|
||||
this.itsSourceFile = sourceFile;
|
||||
this.encodedSource = encodedSource;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
InterpreterData(InterpreterData parent)
|
||||
{
|
||||
this.parentData = parent;
|
||||
this.securityController = parent.securityController;
|
||||
this.securityDomain = parent.securityDomain;
|
||||
this.languageVersion = parent.languageVersion;
|
||||
this.itsSourceFile = parent.itsSourceFile;
|
||||
this.encodedSource = parent.encodedSource;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
itsICodeTop = INITIAL_MAX_ICODE_LENGTH;
|
||||
itsICode = new byte[itsICodeTop];
|
||||
|
||||
itsStringTable = new String[INITIAL_STRINGTABLE_SIZE];
|
||||
|
||||
this.securityDomain = securityDomain;
|
||||
this.languageVersion = languageVersion;
|
||||
}
|
||||
|
||||
SecurityController securityController;
|
||||
Object securityDomain;
|
||||
|
||||
String itsName;
|
||||
String itsSourceFile;
|
||||
boolean itsNeedsActivation;
|
||||
@ -88,8 +113,6 @@ final class InterpreterData implements Serializable, DebuggableScript
|
||||
|
||||
int itsMaxCalleeArgs;
|
||||
|
||||
Object securityDomain;
|
||||
|
||||
String encodedSource;
|
||||
int encodedSourceStart;
|
||||
int encodedSourceEnd;
|
||||
|
@ -559,16 +559,8 @@ public final class JavaAdapter
|
||||
|
||||
private static Class loadAdapterClass(String className, byte[] classBytes)
|
||||
{
|
||||
Context cx = Context.getContext();
|
||||
ClassLoader parentLoader = cx.getApplicationClassLoader();
|
||||
GeneratedClassLoader loader;
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
if (sc == null) {
|
||||
loader = cx.createClassLoader(parentLoader);
|
||||
} else {
|
||||
Object securityDomain = sc.getDynamicSecurityDomain(null);
|
||||
loader = sc.createClassLoader(parentLoader, securityDomain);
|
||||
}
|
||||
GeneratedClassLoader loader
|
||||
= SecurityController.createLoader(null, null);
|
||||
Class result = loader.defineClass(className, classBytes);
|
||||
loader.linkClass(result);
|
||||
return result;
|
||||
|
@ -62,8 +62,8 @@ package org.mozilla.javascript;
|
||||
* @see java.lang.ClassLoader
|
||||
* @since 1.5 Release 4
|
||||
*/
|
||||
public abstract class SecurityController {
|
||||
|
||||
public abstract class SecurityController
|
||||
{
|
||||
/**
|
||||
* Get class loader-like object that can be used
|
||||
* to define classes with the given security context.
|
||||
@ -72,8 +72,40 @@ public abstract class SecurityController {
|
||||
* @param securityDomain some object specifying the security
|
||||
* context of the code that is defined by the returned class loader.
|
||||
*/
|
||||
public abstract GeneratedClassLoader
|
||||
createClassLoader(ClassLoader parentLoader, Object securityDomain);
|
||||
public abstract GeneratedClassLoader createClassLoader(
|
||||
ClassLoader parentLoader, Object securityDomain);
|
||||
|
||||
/**
|
||||
* Create {@link GeneratedClassLoader} with restrictions imposed by
|
||||
* staticDomain and all current stack frames.
|
||||
* The method uses the SecurityController instance associated with the
|
||||
* current {@link Context} to construct proper dynamic domain and create
|
||||
* corresponding class loader.
|
||||
* <par>
|
||||
* If no SecurityController is associated with the current {@link Context} ,
|
||||
* the method calls {@link Context#createClassLoader(ClassLoader parent)}.
|
||||
*
|
||||
* @param parent parent class loader. If null,
|
||||
* {@link Context#getApplicationClassLoader()} will be used.
|
||||
* @param staticDomain static security domain.
|
||||
*/
|
||||
public static GeneratedClassLoader createLoader(
|
||||
ClassLoader parent, Object staticDomain)
|
||||
{
|
||||
Context cx = Context.getContext();
|
||||
if (parent == null) {
|
||||
parent = cx.getApplicationClassLoader();
|
||||
}
|
||||
SecurityController sc = cx.getSecurityController();
|
||||
GeneratedClassLoader loader;
|
||||
if (sc == null) {
|
||||
loader = cx.createClassLoader(parent);
|
||||
} else {
|
||||
Object dynamicDomain = sc.getDynamicSecurityDomain(staticDomain);
|
||||
loader = sc.createClassLoader(parent, dynamicDomain);
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dynamic security domain that allows an action only if it is allowed
|
||||
|
@ -54,14 +54,14 @@ import java.lang.reflect.Constructor;
|
||||
|
||||
public class Codegen extends Interpreter
|
||||
{
|
||||
public Object compile(Context cx, Scriptable scope,
|
||||
public Object compile(Scriptable scope,
|
||||
CompilerEnvirons compilerEnv,
|
||||
ScriptOrFnNode scriptOrFn,
|
||||
String encodedSource,
|
||||
boolean returnFunction,
|
||||
SecurityController securityController,
|
||||
Object securityDomain)
|
||||
{
|
||||
Context cx = Context.getCurrentContext();
|
||||
OptClassNameHelper
|
||||
nameHelper = (OptClassNameHelper)ClassNameHelper.get(cx);
|
||||
Class[] interfaces = nameHelper.getTargetImplements();
|
||||
@ -120,14 +120,8 @@ public class Codegen extends Interpreter
|
||||
|
||||
Exception e = null;
|
||||
Class result = null;
|
||||
ClassLoader parentLoader = cx.getApplicationClassLoader();
|
||||
GeneratedClassLoader loader;
|
||||
if (securityController == null) {
|
||||
loader = cx.createClassLoader(parentLoader);
|
||||
} else {
|
||||
loader = securityController.createClassLoader(parentLoader,
|
||||
securityDomain);
|
||||
}
|
||||
GeneratedClassLoader
|
||||
loader = SecurityController.createLoader(null, securityDomain);
|
||||
|
||||
try {
|
||||
result = loader.defineClass(mainClassName, mainClassBytes);
|
||||
|
Loading…
Reference in New Issue
Block a user