PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/eclipseWorkspace/dojox/secure/sandbox.js.uncompressed.js

https://bitbucket.org/rosudrag/tfgm-bus-whereabouts
JavaScript | 347 lines | 245 code | 6 blank | 96 comment | 50 complexity | badaab059d2221dbab19a82c2c39f13f MD5 | raw file
  1. // wrapped by build app
  2. 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){
  3. dojo.provide("dojox.secure.sandbox");
  4. dojo.require("dojox.secure.DOM");
  5. dojo.require("dojox.secure.capability");
  6. dojo.require("dojo.NodeList-fx");
  7. dojo.require("dojo._base.url");
  8. (function() {
  9. var oldTimeout = setTimeout;
  10. var oldInterval = setInterval;
  11. if({}.__proto__){
  12. // mozilla has unsafe methods on array
  13. var fixMozArrayFunction = function (name) {
  14. var method = Array.prototype[name];
  15. if(method && !method.fixed){
  16. (Array.prototype[name] = function () {
  17. if (this == window) {
  18. throw new TypeError("Called with wrong this");
  19. }
  20. return method.apply(this, arguments);
  21. }).fixed = true;
  22. }
  23. };
  24. // these are not safe in mozilla
  25. fixMozArrayFunction('concat');
  26. fixMozArrayFunction('reverse');
  27. fixMozArrayFunction('sort');
  28. fixMozArrayFunction("slice");
  29. fixMozArrayFunction("forEach");
  30. fixMozArrayFunction("filter");
  31. fixMozArrayFunction("reduce");
  32. fixMozArrayFunction("reduceRight");
  33. fixMozArrayFunction("every");
  34. fixMozArrayFunction("map");
  35. fixMozArrayFunction("some");
  36. }
  37. var xhrGet = function(){
  38. return dojo.xhrGet.apply(dojo,arguments);
  39. };
  40. dojox.secure.sandbox = function(element) {
  41. // summary:
  42. // Creates a secure sandbox from which scripts and HTML can be loaded that
  43. // will only be able to access the provided element and it's descendants, the
  44. // rest of the DOM and JS environment will not be accessible to the sandboxed
  45. // scripts and HTML.
  46. //
  47. // element:
  48. // The DOM element to use as the container for the sandbox
  49. //
  50. // description:
  51. // This function will create and return a sandbox object (see dojox.secure.__Sandbox)
  52. // for the provided element.
  53. var wrap = dojox.secure.DOM(element);
  54. element = wrap(element);
  55. var document = element.ownerDocument;
  56. var mixin, dojo = dojox.secure._safeDojoFunctions(element,wrap);
  57. var imports= [];
  58. var safeCalls = ["isNaN","isFinite","parseInt","parseFloat","escape","unescape",
  59. "encodeURI","encodeURIComponent","decodeURI","decodeURIComponent",
  60. "alert","confirm","prompt", // some people may not want to allow these to be called, but they don't break capability-limiting
  61. "Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError",
  62. "Date","RegExp","Number","Object","Array","String","Math",
  63. //"ADSAFE", // not using ADSAFE runtime for the time being
  64. "setTimeout","setInterval","clearTimeout","clearInterval", // we make these safe below
  65. "dojo","get","set","forEach","load","evaluate"];
  66. for(var i in dojo){
  67. safeCalls.push(i); // add the safe dojo functions to as available global top level functions
  68. imports.push("var " + i + "=dojo." + i); // add to the list of imports
  69. }
  70. // open the dojo namespace (namespaces are pretty silly in an environment where you can't set globals)
  71. eval(imports.join(";"));
  72. function get(obj,prop) {
  73. // basic access by index function
  74. prop = '' + prop;
  75. if(dojox.secure.badProps.test(prop)) {
  76. throw new Error("bad property access");
  77. }
  78. if(obj.__get__) {
  79. return obj.__get__(prop);
  80. }
  81. return obj[prop];
  82. }
  83. function set(obj,prop,value) {
  84. // basic set by index function
  85. prop = '' + prop;
  86. get(obj,prop); // test it
  87. if(obj.__set) {
  88. return obj.__set(prop);
  89. }
  90. obj[prop] = value;
  91. return value;
  92. }
  93. function forEach(obj,fun) {
  94. // short syntax iterator function
  95. if(typeof fun != "function"){
  96. throw new TypeError();
  97. }
  98. if("length" in obj) {
  99. // do arrays the fast way
  100. if(obj.__get__) {
  101. // use the catch getter
  102. var len = obj.__get__('length');
  103. for (var i = 0; i < len; i++) {
  104. if(i in obj) {
  105. fun.call(obj, obj.__get__(i), i, obj);
  106. }
  107. }
  108. }
  109. else {
  110. // fast
  111. len = obj.length;
  112. for (i = 0; i < len; i++) {
  113. if(i in obj) {
  114. fun.call(obj, obj[i], i, obj);
  115. }
  116. }
  117. }
  118. }
  119. else {
  120. // for each an object
  121. for (i in obj) {
  122. fun.call(obj, get(obj,i), i, obj);
  123. }
  124. }
  125. }
  126. function Class(/*Function*/superclass, /*Object*/properties, /*Object*/classProperties) {
  127. // summary:
  128. // A safe class constructor
  129. //
  130. // superclass:
  131. // There may be zero or more superclass arguments. The constructed class
  132. // will inherit from any provided superclasses, protypically from the first,
  133. // via mixin for the subsequent. Later arguments
  134. // will override properties/methods from earlier arguments
  135. //
  136. // properties:
  137. // The constructed
  138. // "class" will also have the methods/properties defined in this argument.
  139. // These methods may utilize the <em>this</em> operator, and they
  140. // are only the code that has access to <em>this</em>. Inner functions
  141. // are also prohibited from using <em>this</em>.
  142. //
  143. // If no superclasses are provided, this object will be the prototype of the
  144. // constructed class (no copying
  145. // will be done). Consequently you can "beget" by calling new (Class(obj)).
  146. // All methods are "bound", each call results in |this| safety checking call.
  147. //
  148. // classProperties:
  149. // This properties will be copied to the new class function.
  150. //
  151. // Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
  152. // they are completely unsecure. This class constructor is conceptually based on declare
  153. // but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
  154. //
  155. // example:
  156. // | var Car = Class({drive:function(speed) { ... } ); // create a Car class with a "drive" method
  157. // | var FastCar = Class(Car,{driveFast: function(speed) { return this.drive(2 * speed); } }); // create a FastCar that extends Car
  158. // | var fastCar = new FastCar; // instantiate
  159. // | fastCar.driveFast(50); // call a method
  160. // | var driveFast = fastCar.driveFast;
  161. // | var driveFast(50); // this will throw an error, the method can be used with an object that is not an instance of FastCar
  162. var proto,superConstructor,ourConstructor;
  163. var arg;
  164. for (var i = 0, l = arguments.length; typeof (arg = arguments[i]) == 'function' && i < l; i++) {
  165. // go through each superclass argument
  166. if(proto) { // we have a prototype now, we must mixin now
  167. mixin(proto,arg.prototype);
  168. }
  169. else {
  170. // this is the first argument, so we can define the prototype ourselves
  171. // link up the prototype chain to the superclass's prototype, so we are a subtype
  172. superConstructor = arg;
  173. var F = function() {};
  174. F.prototype = arg.prototype;
  175. proto = new F;
  176. }
  177. }
  178. if(arg) { // the next object should be the properties
  179. // apply binding checking on all the functions
  180. for (var j in arg) {
  181. // TODO: check on non-enumerables?
  182. var value = arg[j];
  183. if(typeof value == 'function') {
  184. arg[j] = function() {
  185. if(this instanceof Class){
  186. return arguments.callee.__rawMethod__.apply(this,arguments);
  187. }
  188. throw new Error("Method called on wrong object");
  189. };
  190. arg[j].__rawMethod__ = value; // may want to use this for reconstruction and toString,valueOf
  191. }
  192. }
  193. if(arg.hasOwnProperty('constructor')) {
  194. ourConstructor = arg.constructor;
  195. }
  196. }
  197. proto = proto ? mixin(proto,arg) : arg; // if there is no proto yet, we can use the provided object
  198. function Class() {
  199. // the super class may not have been constructed using the same technique, we will just call the constructor
  200. if(superConstructor){
  201. superConstructor.apply(this,arguments);
  202. }
  203. if(ourConstructor){
  204. ourConstructor.apply(this,arguments);
  205. }
  206. }
  207. mixin(Class,arguments[i]); // the optional second object adds properties to the class
  208. proto.constructor = Class;
  209. Class.prototype = proto;
  210. return Class;
  211. }
  212. function checkString(func){
  213. if(typeof func != 'function') {
  214. throw new Error("String is not allowed in setTimeout/setInterval");
  215. }
  216. }
  217. function setTimeout(func,time) {
  218. // sandboxed setTimeout
  219. checkString(func);
  220. return oldTimeout(func,time);
  221. }
  222. function setInterval(func,time) {
  223. // sandboxed setInterval
  224. checkString(func);
  225. return oldInterval(func,time);
  226. }
  227. function evaluate(script){
  228. // sandboxed eval
  229. return wrap.evaluate(script);
  230. }
  231. var load = wrap.load = function(url){
  232. // provides a loader function for the sandbox
  233. if (url.match(/^[\w\s]*:/)){
  234. throw new Error("Access denied to cross-site requests");
  235. }
  236. return xhrGet({url:(new dojo._Url(wrap.rootUrl,url))+'',secure:true});
  237. }
  238. wrap.evaluate = function(script){
  239. //if(!alreadyValidated) {
  240. dojox.secure.capability.validate(script,safeCalls, // the safe dojo library and standard operators
  241. {document:1,element:1}); // these are secured DOM starting points
  242. //}
  243. if(script.match(/^\s*[\[\{]/)) {
  244. var result = eval('(' + script + ')');
  245. // TODO: call render on result?
  246. }
  247. else {
  248. eval(script);
  249. }
  250. //eval('wrap.evaluate=('+arguments.callee.toString()+')'); // yeah, recursive scoping;
  251. };
  252. return /*===== dojo.declare("dojox.secure.__Sandbox", null, =====*/ { // dojox.secure.__Sandbox
  253. loadJS : function(url){
  254. // summary:
  255. // Loads the script from the given URL using XHR (assuming
  256. // a plugin system is in place for cross-site requests) within the sandbox
  257. //
  258. // url:
  259. // The url of the script to load
  260. wrap.rootUrl = url;
  261. return xhrGet({url:url,secure:true}).addCallback(function(result) {
  262. evaluate(result,element /*If we get the results with a secure proxy, we would call put true here */);
  263. });
  264. },
  265. loadHTML : function(url){
  266. // summary:
  267. // Loads the web page from the provided URL using XHR (assuming the
  268. // plugin system is in place) within the sandbox. All scripts within the web
  269. // page will also be sandboxed.
  270. //
  271. // url:
  272. // The url of the web page to load
  273. wrap.rootUrl = url;
  274. return xhrGet({url:url,secure:true}).addCallback(function(result){
  275. element.innerHTML = result;
  276. });
  277. },
  278. evaluate : function(script){
  279. // summary:
  280. // Evaluates the given script within the sandbox
  281. //
  282. // script:
  283. // The JavaScript text to evaluate
  284. return wrap.evaluate(script);
  285. }
  286. // TODO: could add something for pre-validated scripts
  287. }/*===== ) =====*/;
  288. };
  289. })();
  290. dojox.secure._safeDojoFunctions = function(element,wrap) {
  291. // Creates a safe subset of Dojo core library
  292. var safeFunctions = ["mixin","require","isString","isArray","isFunction","isObject","isArrayLike","isAlien",
  293. "hitch","delegate","partial","trim","disconnect","subscribe","unsubscribe","Deferred","toJson","style","attr"];
  294. //var domFunctions = ["clone","byId"];
  295. var doc = element.ownerDocument;
  296. var unwrap = dojox.secure.unwrap;
  297. dojo.NodeList.prototype.addContent.safetyCheck = function(content){
  298. wrap.safeHTML(content);
  299. };
  300. dojo.NodeList.prototype.style.safetyCheck = function(name,value){
  301. if(name=='behavior'){
  302. throw new Error("Can not set behavior");
  303. }
  304. wrap.safeCSS(value);
  305. };
  306. dojo.NodeList.prototype.attr.safetyCheck = function(name,value){
  307. if (value && (name == 'src' || name == 'href' || name=='style')){
  308. throw new Error("Illegal to set " + name);
  309. }
  310. };
  311. var safe = {
  312. query : function(query,root) {
  313. return wrap(dojo.query(query,unwrap(root || element))); // wrap the NodeList
  314. },
  315. connect: function(el,event) {
  316. var obj = el;
  317. arguments[0] = unwrap(el);
  318. if(obj!=arguments[0] && event.substring(0,2) != 'on'){
  319. // it is probably an element, and it doesn't look like an event handler, probably not safe
  320. throw new Error("Invalid event name for element");
  321. }
  322. return dojo.connect.apply(dojo,arguments);
  323. },
  324. body : function() {
  325. return element;
  326. },
  327. byId : function(id) {
  328. return element.ownerDocument.getElementById(id); // use the safe document
  329. },
  330. fromJson : function(str) {
  331. // make sure it is safe before passing it to the unsafe dojo.fromJson
  332. dojox.secure.capability.validate(str,[],{});
  333. return dojo.fromJson(str);
  334. }
  335. };
  336. for (var i = 0; i < safeFunctions.length; i++) {
  337. safe[safeFunctions[i]] = dojo[safeFunctions[i]];
  338. }
  339. return safe;
  340. };
  341. });