diff options
Diffstat (limited to 'js/dojo-1.6/dojox/secure/DOM.xd.js')
| -rw-r--r-- | js/dojo-1.6/dojox/secure/DOM.xd.js | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/secure/DOM.xd.js b/js/dojo-1.6/dojox/secure/DOM.xd.js new file mode 100644 index 0000000..d1e9a43 --- /dev/null +++ b/js/dojo-1.6/dojox/secure/DOM.xd.js @@ -0,0 +1,273 @@ +/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.secure.DOM"],
+["require", "dojox.lang.observable"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.secure.DOM"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.secure.DOM"] = true;
+dojo.provide("dojox.secure.DOM");
+dojo.require("dojox.lang.observable");
+
+dojox.secure.DOM = function(element){
+ function safeNode(node){
+ if(!node){
+ return node;
+ }
+ var parent = node;
+ do {
+ if(parent == element){
+ return wrap(node);
+ }
+ } while((parent = parent.parentNode));
+ return null;
+ }
+ function wrap(result){
+ if(result){
+ if(result.nodeType){
+ // wrap the node
+ var wrapped = nodeObserver(result);
+ if(result.nodeType == 1 && typeof wrapped.style == 'function'){ // if it is a function, that means it is holding a slot for us, now we will override it
+ wrapped.style = styleObserver(result.style);
+ wrapped.ownerDocument = safeDoc;
+ wrapped.childNodes = {__get__:function(i){
+ return wrap(result.childNodes[i]);
+ },
+ length:0
+ };
+ //TODO: maybe add attributes
+ }
+ return wrapped;
+ }
+ if(result && typeof result == 'object'){
+ if(result.__observable){
+ // we have already wrapped it, this helps prevent circular/infinite loops
+ return result.__observable;
+ }
+ // wrap the node list
+ wrapped = result instanceof Array ? [] : {};
+ result.__observable = wrapped;
+ for(var i in result){
+ if (i != '__observable'){
+ wrapped[i] = wrap(result[i]);
+ }
+ }
+ wrapped.data__ = result;
+
+ return wrapped;
+ }
+ if(typeof result == 'function'){
+ var unwrap = function(result){
+ if(typeof result == 'function'){
+ // if untrusted code passes a function to trusted code, we want the trusted code to be
+ // able to execute it and have the arguments automatically wrapped
+ return function(){
+ for (var i = 0; i < arguments.length; i++){
+ arguments[i] = wrap(arguments[i]);
+ }
+ return unwrap(result.apply(wrap(this),arguments));
+ }
+ }
+ return dojox.secure.unwrap(result);
+ };
+ // when we wrap a function we make it so that we can untrusted code can execute
+ // the function and the arguments will be unwrapped for the trusted code
+ return function(){
+ if(result.safetyCheck){
+ result.safetyCheck.apply(unwrap(this),arguments);
+ }
+ for (var i = 0; i < arguments.length; i++){
+ arguments[i] = unwrap(arguments[i]);
+ }
+ return wrap(result.apply(unwrap(this),arguments));
+ }
+ }
+ }
+ return result;
+ }
+ unwrap = dojox.secure.unwrap;
+
+ function safeCSS(css){
+ css += ''; // make sure it is a string
+ if(css.match(/behavior:|content:|javascript:|binding|expression|\@import/)){
+ throw new Error("Illegal CSS");
+ }
+ var id = element.id || (element.id = "safe" + ('' + Math.random()).substring(2));
+ return css.replace(/(\}|^)\s*([^\{]*\{)/g,function(t,a,b){ // put all the styles in the context of the id of the sandbox
+ return a + ' #' + id + ' ' + b; // need to remove body and html references something like: .replace(/body/g,''); but that would break mybody...
+ });
+ }
+ function safeURL(url){
+ // test a url to see if it is safe
+ if(url.match(/:/) && !url.match(/^(http|ftp|mailto)/)){
+ throw new Error("Unsafe URL " + url);
+ }
+ }
+ function safeElement(el){
+ // test an element to see if it is safe
+ if(el && el.nodeType == 1){
+ if(el.tagName.match(/script/i)){
+ var src = el.src;
+ if (src && src != ""){
+ // load the src and evaluate it safely
+ el.parentNode.removeChild(el);
+ dojo.xhrGet({url:src,secure:true}).addCallback(function(result){
+ safeDoc.evaluate(result);
+ });
+ }
+ else{
+ //evaluate the script safely and remove it
+ var script = el.innerHTML;
+ el.parentNode.removeChild(el);
+ wrap.evaluate(script);
+ }
+ }
+ if(el.tagName.match(/link/i)){
+ throw new Error("illegal tag");
+ }
+ if(el.tagName.match(/style/i)){
+ var setCSS = function(cssStr){
+ if(el.styleSheet){// IE
+ el.styleSheet.cssText = cssStr;
+ } else {// w3c
+ var cssText = doc.createTextNode(cssStr);
+ if (el.childNodes[0])
+ el.replaceChild(cssText,el.childNodes[0])
+ else
+ el.appendChild(cssText);
+ }
+
+ }
+ src = el.src;
+ if(src && src != ""){
+ alert('src' + src);
+ // try to load it by url and safely load it
+ el.src = null;
+ dojo.xhrGet({url:src,secure:true}).addCallback(function(result){
+ setCSS(safeCSS(result));
+ });
+ }
+ setCSS(safeCSS(el.innerHTML));
+ }
+ if(el.style){
+ safeCSS(el.style.cssText);
+ }
+ if(el.href){
+ safeURL(el.href);
+ }
+ if(el.src){
+ safeURL(el.src);
+ }
+ var attr,i = 0;
+ while ((attr=el.attributes[i++])){
+ if(attr.name.substring(0,2)== "on" && attr.value != "null" && attr.value != ""){ // must remove all the event handlers
+ throw new Error("event handlers not allowed in the HTML, they must be set with element.addEventListener");
+ }
+ }
+ var children = el.childNodes;
+ for (var i =0, l = children.length; i < l; i++){
+ safeElement(children[i]);
+ }
+ }
+ }
+ function safeHTML(html){
+ var div = document.createElement("div");
+ if(html.match(/<object/i))
+ throw new Error("The object tag is not allowed");
+ div.innerHTML = html; // this is safe with an unattached node
+ safeElement(div);
+ return div;
+ }
+ var doc = element.ownerDocument;
+ var safeDoc = {
+ getElementById : function(id){
+ return safeNode(doc.getElementById(id));
+ },
+ createElement : function(name){
+ return wrap(doc.createElement(name));
+ },
+ createTextNode : function(name){
+ return wrap(doc.createTextNode(name));
+ },
+ write : function(str){
+ var div = safeHTML(str);
+ while (div.childNodes.length){
+ // move all these children to the main node
+ element.appendChild(div.childNodes[0]);
+ }
+ }
+ };
+ safeDoc.open = safeDoc.close = function(){}; // no-op functions
+ var setters = {
+ innerHTML : function(node,value){
+ console.log('setting innerHTML');
+ node.innerHTML = safeHTML(value).innerHTML;
+ }
+ };
+ setters.outerHTML = function(node,value){
+ throw new Error("Can not set this property");
+ }; // blocked
+ function domChanger(name,newNodeArg){
+ return function(node,args){
+ safeElement(args[newNodeArg]); // check to make sure the new node is safe
+ return node[name](args[0]);// execute the method
+ };
+ }
+ var invokers = {
+ appendChild : domChanger("appendChild",0),
+ insertBefore : domChanger("insertBefore",0),
+ replaceChild : domChanger("replaceChild",1),
+ cloneNode : function(node,args){
+ return node.cloneNode(args[0]);
+ },
+ addEventListener : function(node,args){
+ dojo.connect(node,'on' + args[0],this,function(event){
+ event = nodeObserver(event || window.event);
+ args[1].call(this,event);
+ });
+ }
+ };
+ invokers.childNodes = invokers.style = invokers.ownerDocument = function(){}; // this is a trick to get these property slots available, they will be overridden
+ function makeObserver(setter){ // we make two of these, but the setter for style nodes is different
+ return dojox.lang.makeObservable(
+ function(node, prop){
+ var result;
+ return node[prop];
+ },setter,
+ function(wrapper, node, methodName, args){
+ for (var i = 0; i < args.length; i++){
+ args[i] = unwrap(args[i]);
+ }
+ if(invokers[methodName]){
+ return wrap(invokers[methodName].call(wrapper,node,args));
+ }
+ return wrap(node[methodName].apply(node,args));
+ },invokers);
+ }
+ var nodeObserver = makeObserver(function(node, prop, value){
+ if(setters[prop]){
+ setters[prop](node,value);
+ }
+ node[prop] = value;
+ });
+ var blockedStyles = {behavior:1,MozBinding:1};
+ var styleObserver = makeObserver(function(node, prop, value){
+ if(!blockedStyles[prop]){
+ node[prop] = safeCSS(value);
+ }
+ });
+ wrap.safeHTML = safeHTML;
+ wrap.safeCSS = safeCSS;
+ return wrap;
+};
+dojox.secure.unwrap = function unwrap(result){
+ return (result && result.data__) || result;
+};
+
+}
+
+}};});
|
