If you call code that is restricted from use in a sandbox due to these security restrictions, the AIR runtime dispatches a JavaScript error: "Adobe AIR runtime security violation for JavaScript code in the application security sandbox." To avoid this error, follow the coding practices described in this section.
Code executing in the application sandbox is restricted from most operations that involve evaluating and executing strings once the document load event has fired and any load event handlers have exited. Attempting to use the following types of JavaScript statements that evaluate and execute potentially insecure strings will generate JavaScript errors:
In addition, the following types of JavaScript statements will fail without generating an unsafe JavaScript error:
Adobe maintains a list of Ajax frameworks known to support the application security sandbox, at http://www.adobe.com/go/airappsandboxframeworks.
The following sections describe how to rewrite scripts to avoid these unsafe JavaScript errors and silent failures for code running in the application sandbox.
In most cases, you can rewrite or restructure an application to avoid security-related JavaScript errors. However, when rewriting or restructuring is not possible, you can load the application content into a different sandbox using the technique described in Loading application content into a non-application sandbox. If that content also must access AIR APIs, you can create a sandbox bridge, as described in Setting up a sandbox bridge interface.
In the application sandbox, the eval() function can only be used before the page load event or during a load event handler. After the page has loaded, calls to eval() will not execute code. However, in the following cases, you can rewrite your code to avoid the use of eval().
Instead of parsing a string to build the property accessor:
eval("obj." + propName + " = " + val);
access properties with bracket notation:
obj[propName] = val;
Replace statements such as the following:
function compile(var1, var2){
eval("var fn = function(){ this."+var1+"(var2) }");
return fn;
}
with:
function compile(var1, var2){
var self = this;
return function(){ self[var1](var2) };
}
Consider a hypothetical JavaScript class defined with the following code:
var CustomClass =
{
Utils:
{
Parser: function(){ alert('constructor') }
},
Data:
{
}
};
var constructorClassName = "CustomClass.Utils.Parser";
The simplest way to create a new instance would be to use eval():
var myObj;
eval('myObj=new ' + constructorClassName +'()')
However, you could avoid the call to eval() by parsing each component of the class name and building the new object using bracket notation:
function getter(str)
{
var obj = window;
var names = str.split('.');
for(var i=0;i<names.length;i++){
if(typeof obj[names[i]]=='undefined'){
var undefstring = names[0];
for(var j=1;j<=i;j++)
undefstring+="."+names[j];
throw new Error(undefstring+" is undefined");
}
obj = obj[names[i]];
}
return obj;
}
To create the new instance, use:
try{
var Parser = getter(constructorClassName);
var a = new Parser();
}catch(e){
alert(e);
}
Replace the string passed as the handler function with a function reference or object. For example, replace a statement such as:
setTimeout("alert('Timeout')", 10);
with:
setTimeout(alert('Timeout'), 10);
Or, when the function requires the this object to be set by the caller, replace a statement such as:
this.appTimer = setInterval("obj.customFunction();", 100);
with the following:
var _self = this;
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);
Calls to new Function(param, body) can be replaced with an inline function declaration or used only before the page load event has been handled.
The code defined in a link using the javascript: URL scheme will be ignored in the application sandbox. No unsafe JavaScript error is generated. You can replace links using javascript: URLs, such as:
<a href="javascript:code()">Click Me</a>
with:
<a href="#" onclick="code()">Click Me</a>
When you use innerHTML or outerHTML to add elements to the DOM of a document, any event callbacks assigned within the statement, such as onclick or onmouseover, are ignored. No security error is generated. Instead, you can assign an id to the new elements and set the event handler callback functions using the addEventListener() method.
For example, given a target element in a document, such as:
<div id="container"></div>
Replace statements such as:
document.getElementById('container').innerHTML =
'<a href="#" onclick="code()">Click Me.</a>';
with:
document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>';
document.getElementById('smith').addEventListener("click", function() { code(); });
Loading script files from outside the application sandbox is not permitted. No security error is generated. All script files that run in the application sandbox must be installed in the application directory. To use external scripts in a page, you must map the page to a different sandbox. See Loading application content into a non-application sandbox.
Calls to document.write() or document.writeln() are ignored after the page load event has been handled. No security error is generated. As an alternative, you can load a new file, or replace the body of the document using DOM manipulation techniques.
Synchronous XMLHttpRequests initiated before the page load event or during a load event handler do not return any content. Asynchronous XMLHttpRequests can be initiated, but do not return until after the load event. After the load event has been handled, synchronous XMLHttpRequests behave normally.
Dynamically created script elements, such as when created with innerHTML or document.createElement() method are ignored.