implemented sandbox for script-generated user level skins

This commit is contained in:
hns 2001-07-30 00:04:07 +00:00
parent 33add5c06b
commit 94c4997e01
3 changed files with 36 additions and 27 deletions

View file

@ -75,7 +75,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
private DbMapping rootMapping, userRootMapping, userMapping;
protected CacheMap skincache = new CacheMap (100);
boolean checkSubnodes;
String charset;
@ -131,6 +131,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
charset = props.getProperty ("charset", "ISO-8859-1");
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
checkSubnodes = !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
try {
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
} catch (Exception ignore) { }
@ -710,7 +712,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
* It is recommended to leave it on except you suffer severe performance problems and know what you do.
*/
public boolean doesSubnodeChecking () {
return !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
return checkSubnodes;
}
}

View file

@ -106,7 +106,7 @@ public class HopExtension {
go.putHiddenProperty("getXmlDocument", new GlobalGetXmlDocument ("getXmlDocument", evaluator, fp));
go.putHiddenProperty("getHtmlDocument", new GlobalGetHtmlDocument ("getHtmlDocument", evaluator, fp));
go.putHiddenProperty("jdomize", new GlobalJDOM ("jdomize", evaluator, fp));
go.putHiddenProperty("getSkin", new GlobalGetSkin ("getSkin", evaluator, fp));
go.putHiddenProperty("getSkin", new GlobalCreateSkin ("getSkin", evaluator, fp));
go.putHiddenProperty("createSkin", new GlobalCreateSkin ("createSkin", evaluator, fp));
go.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, true, false));
go.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, true, true));
@ -569,26 +569,6 @@ public class HopExtension {
}
}
/**
* Get a parsed Skin from the central skin cache if possible, otherwise create it
*/
class GlobalGetSkin extends BuiltinFunctionObject {
GlobalGetSkin (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length != 1 || ESNull.theNull.equals (arguments[0]))
throw new EcmaScriptException ("getSkin must be called with one String argument!");
String str = arguments[0].toString ();
Skin skin = (Skin) app.skincache.get (str);
if (skin == null) {
skin = new Skin (str, app);
app.skincache.put (str, skin);
}
return new ESWrapper (skin, evaluator);
}
}
/**
* Get a parsed Skin from an app-managed skin text
*/
@ -597,9 +577,15 @@ public class HopExtension {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length != 1 || ESNull.theNull.equals (arguments[0]))
throw new EcmaScriptException ("createSkin must be called with one String argument!");
return new ESWrapper (new Skin (arguments[0].toString(), app), evaluator);
if (arguments.length < 1 || arguments.length > 2 || ESNull.theNull.equals (arguments[0]))
throw new EcmaScriptException ("createSkin must be called with one String argument and an optional sandbox parameter!");
String str = arguments[0].toString ();
Skin skin = null;
if (arguments.length == 2 && arguments[1] instanceof ESObject)
skin = new Skin (str, app, (ESObject) arguments[1]);
else
skin = new Skin (str, app);
return new ESWrapper (skin, evaluator);
}
}

View file

@ -25,9 +25,15 @@ public class Skin {
Object[] parts;
Application app;
String source;
ESObject sandbox;
public Skin (String content, Application app) {
this (content, app, null);
}
public Skin (String content, Application app, ESObject sandbox) {
this.app = app;
this.sandbox = sandbox;
parse (content);
}
@ -87,6 +93,7 @@ public class Skin {
String handler;
String name;
Hashtable parameters;
boolean notallowed = false;
public Macro (String str) {
@ -173,12 +180,26 @@ public class Skin {
else if (state <= MACRO)
name = b.toString().trim();
}
if (sandbox != null && name != null) try {
ESValue allow = handler == null ?
sandbox.getProperty ("global", "global".hashCode ()) :
sandbox.getProperty (handler, handler.hashCode ());
allow = ((ESObject) allow).getProperty (name, name.hashCode ());
if (allow == null || allow == ESUndefined.theUndefined)
notallowed = true;
} catch (Exception x) {
notallowed = true;
}
}
public void render (RequestEvaluator reval, ESNode thisNode, ESObject paramObject) throws RedirectException {
if ("response".equalsIgnoreCase (handler)) {
if (notallowed) {
String h = handler == null ? "global" : handler;
reval.res.write ("[Macro "+h+"."+name+" not allowed in sandbox]");
return;
} else if ("response".equalsIgnoreCase (handler)) {
renderFromResponse (reval);
return;
} else if ("request".equalsIgnoreCase (handler)) {