summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/secure
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/secure')
-rw-r--r--js/dojo-1.7.2/dojox/secure/DOM.js262
-rw-r--r--js/dojo-1.7.2/dojox/secure/README50
-rw-r--r--js/dojo-1.7.2/dojox/secure/capability.js134
-rw-r--r--js/dojo-1.7.2/dojox/secure/fromJson.js245
-rw-r--r--js/dojo-1.7.2/dojox/secure/sandbox.js348
5 files changed, 1039 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/secure/DOM.js b/js/dojo-1.7.2/dojox/secure/DOM.js
new file mode 100644
index 0000000..9bff85b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/DOM.js
@@ -0,0 +1,262 @@
+//>>built
+// wrapped by build app
+define("dojox/secure/DOM", ["dijit","dojo","dojox","dojo/require!dojox/lang/observable"], function(dijit,dojo,dojox){
+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;
+};
+
+});
diff --git a/js/dojo-1.7.2/dojox/secure/README b/js/dojo-1.7.2/dojox/secure/README
new file mode 100644
index 0000000..283c829
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/README
@@ -0,0 +1,50 @@
+-------------------------------------------------------------------------------
+DojoX Secure
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 07/04/2008
+-------------------------------------------------------------------------------
+Project state:
+alpha
+-------------------------------------------------------------------------------
+Project authors
+ Kris Zyp (kris@sitepen.com)
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Secure is a collection of tools for security, in particular for working with
+untrusted data and code. The following tools are a part of DojoX Secure:
+
+dojox.secure.capability - Object-capability JavaScript validation. This is
+a validator to run before eval to ensure that a script can't access or modify
+any objects outside of those specifically provided to it.
+
+dojox.secure.sandbox - Provides support for loading web pages, JSON, and scripts
+from other domains using XHR (and XHR plugins) with a safe subset library and
+sandboxed access to the DOM.
+
+dojox.secure.DOM - Provides a DOM facade that restricts access to
+a specified subtree of the DOM. The DOM facade uses getters/setters
+and lettables to emulate the DOM API.
+
+dojox.secure.OAuth - Future project to provide an implementation of OAuth.
+
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (package loader).
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/secure/*
+
+Install into the following directory structure:
+/dojox/secure/
+
+...which should be at the same level as your Dojo checkout.
+
diff --git a/js/dojo-1.7.2/dojox/secure/capability.js b/js/dojo-1.7.2/dojox/secure/capability.js
new file mode 100644
index 0000000..d2a2629
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/capability.js
@@ -0,0 +1,134 @@
+//>>built
+// wrapped by build app
+define("dojox/secure/capability", ["dijit","dojo","dojox"], function(dijit,dojo,dojox){
+dojo.provide("dojox.secure.capability");
+
+dojox.secure.badProps = /^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/;
+dojox.secure.capability = {
+ keywords: ["break", "case", "catch", "const", "continue","debugger", "default", "delete", "do",
+ "else", "enum","false", "finally", "for", "function","if", "in", "instanceof", "new",
+ "null","yield","return", "switch",
+ "throw", "true", "try", "typeof", "var", "void", "while"],
+ validate : function(/*string*/script,/*Array*/safeLibraries,/*Object*/safeGlobals) {
+ // summary:
+ // pass in the text of a script. If it passes and it can be eval'ed, it should be safe.
+ // Note that this does not do full syntax checking, it relies on eval to reject invalid scripts.
+ // There are also known false rejections:
+ // Nesting vars inside blocks will not declare the variable for the outer block
+ // Named functions are not treated as declaration so they are generally not allowed unless the name is declared with a var.
+ // Var declaration that involve multiple comma delimited variable assignments are not accepted
+ //
+ // script:
+ // the script to execute
+ //
+ // safeLibraries:
+ // The safe libraries that can be called (the functions can not be access/modified by the untrusted code, only called)
+ //
+ // safeGlobals:
+ // These globals can be freely interacted with by the untrusted code
+
+
+ var keywords = this.keywords;
+ for (var i = 0; i < keywords.length; i++) {
+ safeGlobals[keywords[i]]=true;
+ }
+ var badThis = "|this| keyword in object literal without a Class call";
+ var blocks = []; // keeps track of the outer references from each inner block
+ if(script.match(/[\u200c-\u200f\u202a-\u202e\u206a-\u206f\uff00-\uffff]/)){
+ throw new Error("Illegal unicode characters detected");
+ }
+ if(script.match(/\/\*@cc_on/)){
+ throw new Error("Conditional compilation token is not allowed");
+ }
+ script = script.replace(/\\["'\\\/bfnrtu]/g, '@'). // borrows some tricks from json.js
+ // now clear line comments, block comments, regular expressions, and strings.
+ // By doing it all at once, the regular expression uses left to right parsing, and the most
+ // left token is read first. It is also more compact.
+ replace(/\/\/.*|\/\*[\w\W]*?\*\/|("[^"]*")|('[^']*')/g,function(t) {
+ return t.match(/^\/\/|^\/\*/) ? ' ' : '0'; // comments are replaced with a space, strings and regex are replaced with a single safe token (0)
+ }).
+ replace(/\.\s*([a-z\$_A-Z][\w\$_]*)|([;,{])\s*([a-z\$_A-Z][\w\$_]*\s*):/g,function(t,prop,prefix,key) {
+ // find all the dot property references, all the object literal keys, and labels
+ prop = prop || key;
+ if(/^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/.test(prop)){
+ throw new Error("Illegal property name " + prop);
+ }
+ return (prefix && (prefix + "0:")) || '~'; // replace literal keys with 0: and replace properties with the innocuous ~
+ });
+ script.replace(/([^\[][\]\}]\s*=)|((\Wreturn|\S)\s*\[\s*\+?)|([^=!][=!]=[^=])/g,function(oper) {// check for illegal operator usages
+ if(!oper.match(/((\Wreturn|[=\&\|\:\?\,])\s*\[)|\[\s*\+$/)){ // the whitelist for [ operator for array initializer context or [+num] syntax
+ throw new Error("Illegal operator " + oper.substring(1));
+ }
+ });
+ script = script.replace(new RegExp("(" + safeLibraries.join("|") + ")[\\s~]*\\(","g"),function(call) { // find library calls and make them look safe
+ return "new("; // turn into a known safe call
+ });
+ function findOuterRefs(block,func) {
+ var outerRefs = {};
+ block.replace(/#\d+/g,function(b) { // graft in the outer references from the inner scopes
+ var refs = blocks[b.substring(1)];
+ for (var i in refs) {
+ if(i == badThis) {
+ throw i;
+ }
+ if(i == 'this' && refs[':method'] && refs['this'] == 1) {
+ // if we are in an object literal the function may be a bindable method, this must only be in the local scope
+ i = badThis;
+ }
+ if(i != ':method'){
+ outerRefs[i] = 2; // the reference is more than just local
+ }
+ }
+ });
+ block.replace(/(\W|^)([a-z_\$A-Z][\w_\$]*)/g,function(t,a,identifier) { // find all the identifiers
+ if(identifier.charAt(0)=='_'){
+ throw new Error("Names may not start with _");
+ }
+ outerRefs[identifier] = 1;
+ });
+ return outerRefs;
+ }
+ var newScript,outerRefs;
+ function parseBlock(t,func,a,b,params,block) {
+ block.replace(/(^|,)0:\s*function#(\d+)/g,function(t,a,b) { // find functions in object literals
+ // note that if named functions are allowed, it could be possible to have label: function name() {} which is a security breach
+ var refs = blocks[b];
+ refs[':method'] = 1;//mark it as a method
+ });
+ block = block.replace(/(^|[^_\w\$])Class\s*\(\s*([_\w\$]+\s*,\s*)*#(\d+)/g,function(t,p,a,b) { // find Class calls
+ var refs = blocks[b];
+ delete refs[badThis];
+ return (p||'') + (a||'') + "#" + b;
+ });
+ outerRefs = findOuterRefs(block,func); // find the variables in this block
+ function parseVars(t,a,b,decl) { // find var decls
+ decl.replace(/,?([a-z\$A-Z][_\w\$]*)/g,function(t,identifier) {
+ if(identifier == 'Class'){
+ throw new Error("Class is reserved");
+ }
+ delete outerRefs[identifier]; // outer reference is safely referenced here
+ });
+ }
+
+ if(func) {
+ parseVars(t,a,a,params); // the parameters are declare variables
+ }
+ block.replace(/(\W|^)(var) ([ \t,_\w\$]+)/g,parseVars); // and vars declare variables
+ // FIXME: Give named functions #name syntax so they can be detected as vars in outer scopes (but be careful of nesting)
+ return (a || '') + (b || '') + "#" + (blocks.push(outerRefs)-1); // return a block reference so the outer block can fetch it
+ }
+ do {
+ // get all the blocks, starting with inside and moving out, capturing the parameters of functions and catchs as variables along the way
+ newScript = script.replace(/((function|catch)(\s+[_\w\$]+)?\s*\(([^\)]*)\)\s*)?{([^{}]*)}/g, parseBlock);
+ }
+ while(newScript != script && (script = newScript)); // keep going until we can't find anymore blocks
+ parseBlock(0,0,0,0,0,script); //findOuterRefs(script); // find the references in the outside scope
+ for (i in outerRefs) {
+ if(!(i in safeGlobals)) {
+ throw new Error("Illegal reference to " + i);
+ }
+ }
+
+ }
+};
+});
diff --git a/js/dojo-1.7.2/dojox/secure/fromJson.js b/js/dojo-1.7.2/dojox/secure/fromJson.js
new file mode 100644
index 0000000..263be3a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/fromJson.js
@@ -0,0 +1,245 @@
+//>>built
+// wrapped by build app
+define("dojox/secure/fromJson", ["dijit","dojo","dojox"], function(dijit,dojo,dojox){
+dojo.provide("dojox.secure.fromJson");
+
+// Used with permission from Mike Samuel of Google (has CCLA), from the json-sans-eval project:
+// http://code.google.com/p/json-sans-eval/
+// Mike Samuel <mikesamuel@gmail.com>
+
+
+
+dojox.secure.fromJson = typeof JSON != "undefined" ? JSON.parse :
+// summary:
+// Parses a string of well-formed JSON text.
+// description:
+// Parses a string of well-formed JSON text. If the input is not well-formed,
+// then behavior is undefined, but it is
+// deterministic and is guaranteed not to modify any object other than its
+// return value.
+//
+// This does not use `eval` so is less likely to have obscure security bugs than
+// json2.js.
+// It is optimized for speed, so is much faster than json_parse.js.
+//
+// This library should be used whenever security is a concern (when JSON may
+// come from an untrusted source), speed is a concern, and erroring on malformed
+// JSON is *not* a concern.
+//
+// json2.js is very fast, but potentially insecure since it calls `eval` to
+// parse JSON data, so an attacker might be able to supply strange JS that
+// looks like JSON, but that executes arbitrary javascript.
+//
+// To configure dojox.secure.fromJson as the JSON parser for all Dojo
+// JSON parsing, simply do:
+// | dojo.require("dojox.secure.fromJson");
+// | dojo.fromJson = dojox.secure.fromJson;
+// or alternately you could configure dojox.secure.fromJson to only handle
+// XHR responses:
+// | dojo._contentHandlers.json = function(xhr){
+// | return dojox.secure.fromJson.fromJson(xhr.responseText);
+// | };
+//
+// json: String
+// per RFC 4627
+// optReviver: Function (this:Object, string, *)
+// optional function
+// that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
+// If supplied, the function is called with a string key, and a value.
+// The value is the property of 'this'. The reviver should return
+// the value to use in its place. So if dates were serialized as
+// {@code { "type": "Date", "time": 1234 }}, then a reviver might look like
+// {@code
+// function (key, value) {
+// if (value && typeof value === 'object' && 'Date' === value.type) {
+// return new Date(value.time);
+// } else {
+// return value;
+// }
+// }}.
+// If the reviver returns {@code undefined} then the property named by key
+// will be deleted from its container.
+// {@code this} is bound to the object containing the specified property.
+// returns: {Object|Array}
+(function () {
+ var number
+ = '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
+ var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]'
+ + '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))';
+ var string = '(?:\"' + oneChar + '*\")';
+
+ // Will match a value in a well-formed JSON file.
+ // If the input is not well-formed, may match strangely, but not in an unsafe
+ // way.
+ // Since this only matches value tokens, it does not match whitespace, colons,
+ // or commas.
+ var jsonToken = new RegExp(
+ '(?:false|true|null|[\\{\\}\\[\\]]'
+ + '|' + number
+ + '|' + string
+ + ')', 'g');
+
+ // Matches escape sequences in a string literal
+ var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
+
+ // Decodes escape sequences in object literals
+ var escapes = {
+ '"': '"',
+ '/': '/',
+ '\\': '\\',
+ 'b': '\b',
+ 'f': '\f',
+ 'n': '\n',
+ 'r': '\r',
+ 't': '\t'
+ };
+ function unescapeOne(_, ch, hex) {
+ return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
+ }
+
+ // A non-falsy value that coerces to the empty string when used as a key.
+ var EMPTY_STRING = new String('');
+ var SLASH = '\\';
+
+ // Constructor to use based on an open token.
+ var firstTokenCtors = { '{': Object, '[': Array };
+
+ var hop = Object.hasOwnProperty;
+
+ return function (json, opt_reviver) {
+ // Split into tokens
+ var toks = json.match(jsonToken);
+ // Construct the object to return
+ var result;
+ var tok = toks[0];
+ var topLevelPrimitive = false;
+ if ('{' === tok) {
+ result = {};
+ } else if ('[' === tok) {
+ result = [];
+ } else {
+ // The RFC only allows arrays or objects at the top level, but the JSON.parse
+ // defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null
+ // at the top level.
+ result = [];
+ topLevelPrimitive = true;
+ }
+
+ // If undefined, the key in an object key/value record to use for the next
+ // value parsed.
+ var key;
+ // Loop over remaining tokens maintaining a stack of uncompleted objects and
+ // arrays.
+ var stack = [result];
+ for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) {
+ tok = toks[i];
+
+ var cont;
+ switch (tok.charCodeAt(0)) {
+ default: // sign or digit
+ cont = stack[0];
+ cont[key || cont.length] = +(tok);
+ key = void 0;
+ break;
+ case 0x22: // '"'
+ tok = tok.substring(1, tok.length - 1);
+ if (tok.indexOf(SLASH) !== -1) {
+ tok = tok.replace(escapeSequence, unescapeOne);
+ }
+ cont = stack[0];
+ if (!key) {
+ if (cont instanceof Array) {
+ key = cont.length;
+ } else {
+ key = tok || EMPTY_STRING; // Use as key for next value seen.
+ break;
+ }
+ }
+ cont[key] = tok;
+ key = void 0;
+ break;
+ case 0x5b: // '['
+ cont = stack[0];
+ stack.unshift(cont[key || cont.length] = []);
+ key = void 0;
+ break;
+ case 0x5d: // ']'
+ stack.shift();
+ break;
+ case 0x66: // 'f'
+ cont = stack[0];
+ cont[key || cont.length] = false;
+ key = void 0;
+ break;
+ case 0x6e: // 'n'
+ cont = stack[0];
+ cont[key || cont.length] = null;
+ key = void 0;
+ break;
+ case 0x74: // 't'
+ cont = stack[0];
+ cont[key || cont.length] = true;
+ key = void 0;
+ break;
+ case 0x7b: // '{'
+ cont = stack[0];
+ stack.unshift(cont[key || cont.length] = {});
+ key = void 0;
+ break;
+ case 0x7d: // '}'
+ stack.shift();
+ break;
+ }
+ }
+ // Fail if we've got an uncompleted object.
+ if (topLevelPrimitive) {
+ if (stack.length !== 1) { throw new Error(); }
+ result = result[0];
+ } else {
+ if (stack.length) { throw new Error(); }
+ }
+
+ if (opt_reviver) {
+ // Based on walk as implemented in http://www.json.org/json2.js
+ var walk = function (holder, key) {
+ var value = holder[key];
+ if (value && typeof value === 'object') {
+ var toDelete = null;
+ for (var k in value) {
+ if (hop.call(value, k) && value !== holder) {
+ // Recurse to properties first. This has the effect of causing
+ // the reviver to be called on the object graph depth-first.
+
+ // Since 'this' is bound to the holder of the property, the
+ // reviver can access sibling properties of k including ones
+ // that have not yet been revived.
+
+ // The value returned by the reviver is used in place of the
+ // current value of property k.
+ // If it returns undefined then the property is deleted.
+ var v = walk(value, k);
+ if (v !== void 0) {
+ value[k] = v;
+ } else {
+ // Deleting properties inside the loop has vaguely defined
+ // semantics in ES3 and ES3.1.
+ if (!toDelete) { toDelete = []; }
+ toDelete.push(k);
+ }
+ }
+ }
+ if (toDelete) {
+ for (var i = toDelete.length; --i >= 0;) {
+ delete value[toDelete[i]];
+ }
+ }
+ }
+ return opt_reviver.call(holder, key, value);
+ };
+ result = walk({ '': result }, '');
+ }
+
+ return result;
+ };
+})();
+});
diff --git a/js/dojo-1.7.2/dojox/secure/sandbox.js b/js/dojo-1.7.2/dojox/secure/sandbox.js
new file mode 100644
index 0000000..70cc782
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/secure/sandbox.js
@@ -0,0 +1,348 @@
+//>>built
+// wrapped by build app
+define("dojox/secure/sandbox", ["dijit","dojo","dojox","dojo/require!dojox/secure/DOM,dojox/secure/capability,dojo/NodeList-fx,dojo/_base/url"], function(dijit,dojo,dojox){
+dojo.provide("dojox.secure.sandbox");
+dojo.require("dojox.secure.DOM");
+dojo.require("dojox.secure.capability");
+dojo.require("dojo.NodeList-fx");
+dojo.require("dojo._base.url");
+
+(function() {
+ var oldTimeout = setTimeout;
+ var oldInterval = setInterval;
+ if({}.__proto__){
+ // mozilla has unsafe methods on array
+ var fixMozArrayFunction = function (name) {
+ var method = Array.prototype[name];
+ if(method && !method.fixed){
+ (Array.prototype[name] = function () {
+ if (this == window) {
+ throw new TypeError("Called with wrong this");
+ }
+ return method.apply(this, arguments);
+ }).fixed = true;
+ }
+ };
+ // these are not safe in mozilla
+ fixMozArrayFunction('concat');
+ fixMozArrayFunction('reverse');
+ fixMozArrayFunction('sort');
+ fixMozArrayFunction("slice");
+ fixMozArrayFunction("forEach");
+ fixMozArrayFunction("filter");
+ fixMozArrayFunction("reduce");
+ fixMozArrayFunction("reduceRight");
+ fixMozArrayFunction("every");
+ fixMozArrayFunction("map");
+ fixMozArrayFunction("some");
+ }
+ var xhrGet = function(){
+ return dojo.xhrGet.apply(dojo,arguments);
+ };
+ dojox.secure.sandbox = function(element) {
+ // summary:
+ // Creates a secure sandbox from which scripts and HTML can be loaded that
+ // will only be able to access the provided element and it's descendants, the
+ // rest of the DOM and JS environment will not be accessible to the sandboxed
+ // scripts and HTML.
+ //
+ // element:
+ // The DOM element to use as the container for the sandbox
+ //
+ // description:
+ // This function will create and return a sandbox object (see dojox.secure.__Sandbox)
+ // for the provided element.
+ var wrap = dojox.secure.DOM(element);
+ element = wrap(element);
+ var document = element.ownerDocument;
+ var mixin, dojo = dojox.secure._safeDojoFunctions(element,wrap);
+ var imports= [];
+ var safeCalls = ["isNaN","isFinite","parseInt","parseFloat","escape","unescape",
+ "encodeURI","encodeURIComponent","decodeURI","decodeURIComponent",
+ "alert","confirm","prompt", // some people may not want to allow these to be called, but they don't break capability-limiting
+ "Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError",
+ "Date","RegExp","Number","Object","Array","String","Math",
+ //"ADSAFE", // not using ADSAFE runtime for the time being
+ "setTimeout","setInterval","clearTimeout","clearInterval", // we make these safe below
+ "dojo","get","set","forEach","load","evaluate"];
+ for(var i in dojo){
+ safeCalls.push(i); // add the safe dojo functions to as available global top level functions
+ imports.push("var " + i + "=dojo." + i); // add to the list of imports
+ }
+ // open the dojo namespace (namespaces are pretty silly in an environment where you can't set globals)
+ eval(imports.join(";"));
+ function get(obj,prop) {
+ // basic access by index function
+ prop = '' + prop;
+ if(dojox.secure.badProps.test(prop)) {
+ throw new Error("bad property access");
+ }
+ if(obj.__get__) {
+ return obj.__get__(prop);
+ }
+ return obj[prop];
+ }
+ function set(obj,prop,value) {
+ // basic set by index function
+ prop = '' + prop;
+ get(obj,prop); // test it
+ if(obj.__set) {
+ return obj.__set(prop);
+ }
+ obj[prop] = value;
+ return value;
+ }
+ function forEach(obj,fun) {
+ // short syntax iterator function
+ if(typeof fun != "function"){
+ throw new TypeError();
+ }
+ if("length" in obj) {
+ // do arrays the fast way
+ if(obj.__get__) {
+ // use the catch getter
+ var len = obj.__get__('length');
+ for (var i = 0; i < len; i++) {
+ if(i in obj) {
+ fun.call(obj, obj.__get__(i), i, obj);
+ }
+ }
+ }
+ else {
+ // fast
+ len = obj.length;
+ for (i = 0; i < len; i++) {
+ if(i in obj) {
+ fun.call(obj, obj[i], i, obj);
+ }
+ }
+ }
+ }
+ else {
+ // for each an object
+ for (i in obj) {
+ fun.call(obj, get(obj,i), i, obj);
+ }
+ }
+ }
+ function Class(/*Function*/superclass, /*Object*/properties, /*Object*/classProperties) {
+ // summary:
+ // A safe class constructor
+ //
+ // superclass:
+ // There may be zero or more superclass arguments. The constructed class
+ // will inherit from any provided superclasses, protypically from the first,
+ // via mixin for the subsequent. Later arguments
+ // will override properties/methods from earlier arguments
+ //
+ // properties:
+ // The constructed
+ // "class" will also have the methods/properties defined in this argument.
+ // These methods may utilize the <em>this</em> operator, and they
+ // are only the code that has access to <em>this</em>. Inner functions
+ // are also prohibited from using <em>this</em>.
+ //
+ // If no superclasses are provided, this object will be the prototype of the
+ // constructed class (no copying
+ // will be done). Consequently you can "beget" by calling new (Class(obj)).
+ // All methods are "bound", each call results in |this| safety checking call.
+ //
+ // classProperties:
+ // This properties will be copied to the new class function.
+ //
+ // Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
+ // they are completely unsecure. This class constructor is conceptually based on declare
+ // but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
+ //
+ // example:
+ // | var Car = Class({drive:function(speed) { ... } ); // create a Car class with a "drive" method
+ // | var FastCar = Class(Car,{driveFast: function(speed) { return this.drive(2 * speed); } }); // create a FastCar that extends Car
+ // | var fastCar = new FastCar; // instantiate
+ // | fastCar.driveFast(50); // call a method
+ // | var driveFast = fastCar.driveFast;
+ // | var driveFast(50); // this will throw an error, the method can be used with an object that is not an instance of FastCar
+ var proto,superConstructor,ourConstructor;
+ var arg;
+ for (var i = 0, l = arguments.length; typeof (arg = arguments[i]) == 'function' && i < l; i++) {
+ // go through each superclass argument
+ if(proto) { // we have a prototype now, we must mixin now
+ mixin(proto,arg.prototype);
+ }
+ else {
+ // this is the first argument, so we can define the prototype ourselves
+ // link up the prototype chain to the superclass's prototype, so we are a subtype
+ superConstructor = arg;
+ var F = function() {};
+ F.prototype = arg.prototype;
+ proto = new F;
+ }
+ }
+
+ if(arg) { // the next object should be the properties
+ // apply binding checking on all the functions
+ for (var j in arg) {
+ // TODO: check on non-enumerables?
+ var value = arg[j];
+ if(typeof value == 'function') {
+ arg[j] = function() {
+ if(this instanceof Class){
+ return arguments.callee.__rawMethod__.apply(this,arguments);
+ }
+ throw new Error("Method called on wrong object");
+ };
+ arg[j].__rawMethod__ = value; // may want to use this for reconstruction and toString,valueOf
+ }
+ }
+ if(arg.hasOwnProperty('constructor')) {
+ ourConstructor = arg.constructor;
+ }
+ }
+ proto = proto ? mixin(proto,arg) : arg; // if there is no proto yet, we can use the provided object
+ function Class() {
+ // the super class may not have been constructed using the same technique, we will just call the constructor
+ if(superConstructor){
+ superConstructor.apply(this,arguments);
+ }
+ if(ourConstructor){
+ ourConstructor.apply(this,arguments);
+ }
+ }
+ mixin(Class,arguments[i]); // the optional second object adds properties to the class
+ proto.constructor = Class;
+ Class.prototype = proto;
+ return Class;
+ }
+ function checkString(func){
+ if(typeof func != 'function') {
+ throw new Error("String is not allowed in setTimeout/setInterval");
+ }
+ }
+ function setTimeout(func,time) {
+ // sandboxed setTimeout
+ checkString(func);
+ return oldTimeout(func,time);
+ }
+ function setInterval(func,time) {
+ // sandboxed setInterval
+ checkString(func);
+ return oldInterval(func,time);
+ }
+ function evaluate(script){
+ // sandboxed eval
+ return wrap.evaluate(script);
+ }
+ var load = wrap.load = function(url){
+ // provides a loader function for the sandbox
+ if (url.match(/^[\w\s]*:/)){
+ throw new Error("Access denied to cross-site requests");
+ }
+ return xhrGet({url:(new dojo._Url(wrap.rootUrl,url))+'',secure:true});
+ }
+ wrap.evaluate = function(script){
+ //if(!alreadyValidated) {
+ dojox.secure.capability.validate(script,safeCalls, // the safe dojo library and standard operators
+ {document:1,element:1}); // these are secured DOM starting points
+
+ //}
+ if(script.match(/^\s*[\[\{]/)) {
+ var result = eval('(' + script + ')');
+ // TODO: call render on result?
+ }
+ else {
+ eval(script);
+ }
+ //eval('wrap.evaluate=('+arguments.callee.toString()+')'); // yeah, recursive scoping;
+ };
+ return /*===== dojo.declare("dojox.secure.__Sandbox", null, =====*/ { // dojox.secure.__Sandbox
+ loadJS : function(url){
+ // summary:
+ // Loads the script from the given URL using XHR (assuming
+ // a plugin system is in place for cross-site requests) within the sandbox
+ //
+ // url:
+ // The url of the script to load
+ wrap.rootUrl = url;
+ return xhrGet({url:url,secure:true}).addCallback(function(result) {
+ evaluate(result,element /*If we get the results with a secure proxy, we would call put true here */);
+ });
+ },
+ loadHTML : function(url){
+ // summary:
+ // Loads the web page from the provided URL using XHR (assuming the
+ // plugin system is in place) within the sandbox. All scripts within the web
+ // page will also be sandboxed.
+ //
+ // url:
+ // The url of the web page to load
+
+ wrap.rootUrl = url;
+ return xhrGet({url:url,secure:true}).addCallback(function(result){
+ element.innerHTML = result;
+ });
+ },
+ evaluate : function(script){
+ // summary:
+ // Evaluates the given script within the sandbox
+ //
+ // script:
+ // The JavaScript text to evaluate
+ return wrap.evaluate(script);
+ }
+ // TODO: could add something for pre-validated scripts
+ }/*===== ) =====*/;
+ };
+})();
+dojox.secure._safeDojoFunctions = function(element,wrap) {
+ // Creates a safe subset of Dojo core library
+ var safeFunctions = ["mixin","require","isString","isArray","isFunction","isObject","isArrayLike","isAlien",
+ "hitch","delegate","partial","trim","disconnect","subscribe","unsubscribe","Deferred","toJson","style","attr"];
+ //var domFunctions = ["clone","byId"];
+ var doc = element.ownerDocument;
+ var unwrap = dojox.secure.unwrap;
+ dojo.NodeList.prototype.addContent.safetyCheck = function(content){
+ wrap.safeHTML(content);
+ };
+ dojo.NodeList.prototype.style.safetyCheck = function(name,value){
+ if(name=='behavior'){
+ throw new Error("Can not set behavior");
+ }
+ wrap.safeCSS(value);
+ };
+ dojo.NodeList.prototype.attr.safetyCheck = function(name,value){
+ if (value && (name == 'src' || name == 'href' || name=='style')){
+ throw new Error("Illegal to set " + name);
+ }
+ };
+ var safe = {
+ query : function(query,root) {
+ return wrap(dojo.query(query,unwrap(root || element))); // wrap the NodeList
+ },
+ connect: function(el,event) {
+ var obj = el;
+ arguments[0] = unwrap(el);
+ if(obj!=arguments[0] && event.substring(0,2) != 'on'){
+ // it is probably an element, and it doesn't look like an event handler, probably not safe
+ throw new Error("Invalid event name for element");
+ }
+ return dojo.connect.apply(dojo,arguments);
+ },
+ body : function() {
+ return element;
+ },
+ byId : function(id) {
+ return element.ownerDocument.getElementById(id); // use the safe document
+ },
+ fromJson : function(str) {
+ // make sure it is safe before passing it to the unsafe dojo.fromJson
+ dojox.secure.capability.validate(str,[],{});
+ return dojo.fromJson(str);
+ }
+ };
+ for (var i = 0; i < safeFunctions.length; i++) {
+ safe[safeFunctions[i]] = dojo[safeFunctions[i]];
+ }
+ return safe;
+};
+
+
+});