Resolving bug 236193: require enetered Context for compilation

This commit is contained in:
igor%mir2.org 2004-03-03 11:20:33 +00:00
parent cb4be12ceb
commit 58db1d9fd5
6 changed files with 110 additions and 63 deletions

View File

@ -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) {

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);