implemented sandbox for script-generated user level skins
This commit is contained in:
parent
33add5c06b
commit
94c4997e01
3 changed files with 36 additions and 27 deletions
|
@ -75,7 +75,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
|
|
||||||
private DbMapping rootMapping, userRootMapping, userMapping;
|
private DbMapping rootMapping, userRootMapping, userMapping;
|
||||||
|
|
||||||
protected CacheMap skincache = new CacheMap (100);
|
boolean checkSubnodes;
|
||||||
|
|
||||||
String charset;
|
String charset;
|
||||||
|
|
||||||
|
@ -131,6 +131,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
charset = props.getProperty ("charset", "ISO-8859-1");
|
charset = props.getProperty ("charset", "ISO-8859-1");
|
||||||
|
|
||||||
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
|
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
|
||||||
|
checkSubnodes = !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
|
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
|
||||||
} catch (Exception ignore) { }
|
} 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.
|
* It is recommended to leave it on except you suffer severe performance problems and know what you do.
|
||||||
*/
|
*/
|
||||||
public boolean doesSubnodeChecking () {
|
public boolean doesSubnodeChecking () {
|
||||||
return !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
|
return checkSubnodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class HopExtension {
|
||||||
go.putHiddenProperty("getXmlDocument", new GlobalGetXmlDocument ("getXmlDocument", evaluator, fp));
|
go.putHiddenProperty("getXmlDocument", new GlobalGetXmlDocument ("getXmlDocument", evaluator, fp));
|
||||||
go.putHiddenProperty("getHtmlDocument", new GlobalGetHtmlDocument ("getHtmlDocument", evaluator, fp));
|
go.putHiddenProperty("getHtmlDocument", new GlobalGetHtmlDocument ("getHtmlDocument", evaluator, fp));
|
||||||
go.putHiddenProperty("jdomize", new GlobalJDOM ("jdomize", 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("createSkin", new GlobalCreateSkin ("createSkin", evaluator, fp));
|
||||||
go.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, true, false));
|
go.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, true, false));
|
||||||
go.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, true, true));
|
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
|
* Get a parsed Skin from an app-managed skin text
|
||||||
*/
|
*/
|
||||||
|
@ -597,9 +577,15 @@ public class HopExtension {
|
||||||
super (fp, evaluator, name, 1);
|
super (fp, evaluator, name, 1);
|
||||||
}
|
}
|
||||||
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
if (arguments.length != 1 || ESNull.theNull.equals (arguments[0]))
|
if (arguments.length < 1 || arguments.length > 2 || ESNull.theNull.equals (arguments[0]))
|
||||||
throw new EcmaScriptException ("createSkin must be called with one String argument!");
|
throw new EcmaScriptException ("createSkin must be called with one String argument and an optional sandbox parameter!");
|
||||||
return new ESWrapper (new Skin (arguments[0].toString(), app), evaluator);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,15 @@ public class Skin {
|
||||||
Object[] parts;
|
Object[] parts;
|
||||||
Application app;
|
Application app;
|
||||||
String source;
|
String source;
|
||||||
|
ESObject sandbox;
|
||||||
|
|
||||||
public Skin (String content, Application app) {
|
public Skin (String content, Application app) {
|
||||||
|
this (content, app, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Skin (String content, Application app, ESObject sandbox) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
this.sandbox = sandbox;
|
||||||
parse (content);
|
parse (content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +93,7 @@ public class Skin {
|
||||||
String handler;
|
String handler;
|
||||||
String name;
|
String name;
|
||||||
Hashtable parameters;
|
Hashtable parameters;
|
||||||
|
boolean notallowed = false;
|
||||||
|
|
||||||
public Macro (String str) {
|
public Macro (String str) {
|
||||||
|
|
||||||
|
@ -173,12 +180,26 @@ public class Skin {
|
||||||
else if (state <= MACRO)
|
else if (state <= MACRO)
|
||||||
name = b.toString().trim();
|
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 {
|
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);
|
renderFromResponse (reval);
|
||||||
return;
|
return;
|
||||||
} else if ("request".equalsIgnoreCase (handler)) {
|
} else if ("request".equalsIgnoreCase (handler)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue