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; | ||||
| 
 | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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)) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue