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) boolean fromEval)
throws IOException 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 // One of sourceReader or sourceString has to be null
if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug(); if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug();
// scope should be given if and only if compiling function // scope should be given if and only if compiling function
@ -2096,19 +2101,12 @@ public class Context
int syntaxErrorCount = compilerEnv.getSyntaxErrorCount(); int syntaxErrorCount = compilerEnv.getSyntaxErrorCount();
if (syntaxErrorCount == 0) { if (syntaxErrorCount == 0) {
Interpreter compiler = createCompiler(); Interpreter compiler = createCompiler();
if (securityController != null) {
securityDomain = securityController.
getDynamicSecurityDomain(securityDomain);
} else {
securityDomain = null;
}
String encodedSource = p.getEncodedSource(); String encodedSource = p.getEncodedSource();
Object result = compiler.compile(this, scope, compilerEnv, Object result = compiler.compile(scope, compilerEnv,
tree, encodedSource, tree, encodedSource,
returnFunction, returnFunction,
securityController,
securityDomain); securityDomain);
syntaxErrorCount = compilerEnv.getSyntaxErrorCount(); syntaxErrorCount = compilerEnv.getSyntaxErrorCount();
if (syntaxErrorCount == 0) { if (syntaxErrorCount == 0) {

View File

@ -110,13 +110,12 @@ public class Interpreter
// Last icode // Last icode
END_ICODE = BASE_ICODE + 30; END_ICODE = BASE_ICODE + 30;
public Object compile(Context cx, Scriptable scope, public Object compile(Scriptable scope,
CompilerEnvirons compilerEnv, CompilerEnvirons compilerEnv,
ScriptOrFnNode tree, ScriptOrFnNode tree,
String encodedSource, String encodedSource,
boolean returnFunction, boolean returnFunction,
SecurityController securityController, Object staticSecurityDomain)
Object securityDomain)
{ {
this.compilerEnv = compilerEnv; this.compilerEnv = compilerEnv;
(new NodeTransformer(compilerEnv)).transform(tree); (new NodeTransformer(compilerEnv)).transform(tree);
@ -129,17 +128,30 @@ public class Interpreter
tree = tree.getFunctionNode(0); 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; scriptOrFn = tree;
itsData = new InterpreterData(securityDomain, itsData = new InterpreterData(sc, dynamicDomain,
compilerEnv.getLanguageVersion()); compilerEnv.getLanguageVersion(),
itsData.itsSourceFile = scriptOrFn.getSourceName(); scriptOrFn.getSourceName(),
itsData.encodedSource = encodedSource; encodedSource);
itsData.topLevel = true; itsData.topLevel = true;
if (tree instanceof FunctionNode) { if (tree instanceof FunctionNode) {
generateFunctionICode(cx); generateFunctionICode();
return createFunction(cx, scope, itsData, false); return createFunction(cx, scope, itsData, false);
} else { } else {
generateICodeFromTree(cx, scriptOrFn); generateICodeFromTree(scriptOrFn);
itsData.itsFromEvalCode = compilerEnv.isFromEval(); itsData.itsFromEvalCode = compilerEnv.isFromEval();
return new InterpretedScript(itsData); return new InterpretedScript(itsData);
} }
@ -169,7 +181,7 @@ public class Interpreter
} }
} }
private void generateFunctionICode(Context cx) private void generateFunctionICode()
{ {
FunctionNode theFunction = (FunctionNode)scriptOrFn; 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; int theICodeTop = 0;
theICodeTop = generateICode(tree, theICodeTop); theICodeTop = generateICode(tree, theICodeTop);
@ -260,7 +272,7 @@ public class Interpreter
if (Token.printICode) dumpICode(itsData); if (Token.printICode) dumpICode(itsData);
} }
private void generateNestedFunctions(Context cx) private void generateNestedFunctions()
{ {
int functionCount = scriptOrFn.getFunctionCount(); int functionCount = scriptOrFn.getFunctionCount();
if (functionCount == 0) return; if (functionCount == 0) return;
@ -271,24 +283,21 @@ public class Interpreter
Interpreter jsi = new Interpreter(); Interpreter jsi = new Interpreter();
jsi.compilerEnv = compilerEnv; jsi.compilerEnv = compilerEnv;
jsi.scriptOrFn = def; jsi.scriptOrFn = def;
jsi.itsData = new InterpreterData(itsData.securityDomain, jsi.itsData = new InterpreterData(itsData);
itsData.languageVersion);
jsi.itsData.parentData = itsData;
jsi.itsData.itsSourceFile = itsData.itsSourceFile;
jsi.itsData.encodedSource = itsData.encodedSource;
jsi.itsData.itsCheckThis = def.getCheckThis(); jsi.itsData.itsCheckThis = def.getCheckThis();
jsi.itsInFunctionFlag = true; jsi.itsInFunctionFlag = true;
jsi.generateFunctionICode(cx); jsi.generateFunctionICode();
array[i] = jsi.itsData; array[i] = jsi.itsData;
} }
itsData.itsNestedFunctions = array; itsData.itsNestedFunctions = array;
} }
private void generateRegExpLiterals(Context cx) private void generateRegExpLiterals()
{ {
int N = scriptOrFn.getRegexpCount(); int N = scriptOrFn.getRegexpCount();
if (N == 0) return; if (N == 0) return;
Context cx = Context.getContext();
RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
Object[] array = new Object[N]; Object[] array = new Object[N];
for (int i = 0; i != N; i++) { for (int i = 0; i != N; i++) {
@ -1857,8 +1866,7 @@ public class Interpreter
if (argsDbl != null) { if (argsDbl != null) {
args = getArgsArray(args, argsDbl, argShift, argCount); args = getArgsArray(args, argsDbl, argShift, argCount);
} }
SecurityController sc = cx.getSecurityController(); SecurityController sc = idata.securityController;
Object savedDomain = cx.interpreterSecurityDomain; Object savedDomain = cx.interpreterSecurityDomain;
cx.interpreterSecurityDomain = idata.securityDomain; cx.interpreterSecurityDomain = idata.securityDomain;
try { try {

View File

@ -49,17 +49,42 @@ final class InterpreterData implements Serializable, DebuggableScript
static final int INITIAL_STRINGTABLE_SIZE = 64; static final int INITIAL_STRINGTABLE_SIZE = 64;
static final int INITIAL_NUMBERTABLE_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; itsICodeTop = INITIAL_MAX_ICODE_LENGTH;
itsICode = new byte[itsICodeTop]; itsICode = new byte[itsICodeTop];
itsStringTable = new String[INITIAL_STRINGTABLE_SIZE]; itsStringTable = new String[INITIAL_STRINGTABLE_SIZE];
this.securityDomain = securityDomain;
this.languageVersion = languageVersion;
} }
SecurityController securityController;
Object securityDomain;
String itsName; String itsName;
String itsSourceFile; String itsSourceFile;
boolean itsNeedsActivation; boolean itsNeedsActivation;
@ -88,8 +113,6 @@ final class InterpreterData implements Serializable, DebuggableScript
int itsMaxCalleeArgs; int itsMaxCalleeArgs;
Object securityDomain;
String encodedSource; String encodedSource;
int encodedSourceStart; int encodedSourceStart;
int encodedSourceEnd; int encodedSourceEnd;

View File

@ -559,16 +559,8 @@ public final class JavaAdapter
private static Class loadAdapterClass(String className, byte[] classBytes) private static Class loadAdapterClass(String className, byte[] classBytes)
{ {
Context cx = Context.getContext(); GeneratedClassLoader loader
ClassLoader parentLoader = cx.getApplicationClassLoader(); = SecurityController.createLoader(null, null);
GeneratedClassLoader loader;
SecurityController sc = cx.getSecurityController();
if (sc == null) {
loader = cx.createClassLoader(parentLoader);
} else {
Object securityDomain = sc.getDynamicSecurityDomain(null);
loader = sc.createClassLoader(parentLoader, securityDomain);
}
Class result = loader.defineClass(className, classBytes); Class result = loader.defineClass(className, classBytes);
loader.linkClass(result); loader.linkClass(result);
return result; return result;

View File

@ -62,8 +62,8 @@ package org.mozilla.javascript;
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
* @since 1.5 Release 4 * @since 1.5 Release 4
*/ */
public abstract class SecurityController { public abstract class SecurityController
{
/** /**
* Get class loader-like object that can be used * Get class loader-like object that can be used
* to define classes with the given security context. * to define classes with the given security context.
@ -72,8 +72,40 @@ public abstract class SecurityController {
* @param securityDomain some object specifying the security * @param securityDomain some object specifying the security
* context of the code that is defined by the returned class loader. * context of the code that is defined by the returned class loader.
*/ */
public abstract GeneratedClassLoader public abstract GeneratedClassLoader createClassLoader(
createClassLoader(ClassLoader parentLoader, Object securityDomain); 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 * 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 class Codegen extends Interpreter
{ {
public Object compile(Context cx, Scriptable scope, public Object compile(Scriptable scope,
CompilerEnvirons compilerEnv, CompilerEnvirons compilerEnv,
ScriptOrFnNode scriptOrFn, ScriptOrFnNode scriptOrFn,
String encodedSource, String encodedSource,
boolean returnFunction, boolean returnFunction,
SecurityController securityController,
Object securityDomain) Object securityDomain)
{ {
Context cx = Context.getCurrentContext();
OptClassNameHelper OptClassNameHelper
nameHelper = (OptClassNameHelper)ClassNameHelper.get(cx); nameHelper = (OptClassNameHelper)ClassNameHelper.get(cx);
Class[] interfaces = nameHelper.getTargetImplements(); Class[] interfaces = nameHelper.getTargetImplements();
@ -120,14 +120,8 @@ public class Codegen extends Interpreter
Exception e = null; Exception e = null;
Class result = null; Class result = null;
ClassLoader parentLoader = cx.getApplicationClassLoader(); GeneratedClassLoader
GeneratedClassLoader loader; loader = SecurityController.createLoader(null, securityDomain);
if (securityController == null) {
loader = cx.createClassLoader(parentLoader);
} else {
loader = securityController.createClassLoader(parentLoader,
securityDomain);
}
try { try {
result = loader.defineClass(mainClassName, mainClassBytes); result = loader.defineClass(mainClassName, mainClassBytes);