Skip to content

Instantly share code, notes, and snippets.

@vmysla
Created September 5, 2015 03:54
Show Gist options
  • Save vmysla/1c1ccf4c7bc2a112cbca to your computer and use it in GitHub Desktop.
Save vmysla/1c1ccf4c7bc2a112cbca to your computer and use it in GitHub Desktop.
window.onBeforeError( myJavaScriptFunction ) with safer.js
///////////////////////////////////////////////////////
var safer = require_saferjs();
///////////////////////////////////////////////////////
var myObject = getBuggyCode();
///////////////////////////////////////////////////////
console.clear();
console.log('////////// Example #1: safer.js /////////////');
console.info('expected output : undefined 10 undefined "yourBar"');
console.info('expected exception : ');
console.info('actuals:');
myObject = getBuggyCode();
myObject.myMethod("code is safe by defaults");
console.log('////////// Example #2: safer.failsafe /////////////');
console.info('expected output : ');
console.info('expected exception : ReferenceError: nonExistingObject is not defined');
console.info('actuals:');
safer.failsafe = false;
try {
myObject = getBuggyCode();
myObject.myMethod("code is safe by defaults, but is OFF for now");
}
catch(e){
console.error(e);
}
console.log('////////// Example #3: safer.onbeforeerror /////////////');
console.info('expected warning : Variable nonExistingObjectmight cause uncaught ReferenceError in nonExistingObject[\'XXX\'] expression');
console.info('expected output : undefined "code errors can be catched before they happen" undefined "yourBar"n');
console.info('expected exception : ');
console.info('actuals:');
safer.failsafe = true;
safer.onbeforeerror = function(variable, expression){
console.warn('Variable '+variable+'might cause uncaught ReferenceError in '+expression+' expression');
}
myObject = getBuggyCode();
myObject.myMethod("code errors can be catched before they happen");
console.log('/////////////////////////////////////////////////////////');
function getBuggyCode(){
var myObject = {
myFoo : 'yourBar',
myMethod : safer(
function x(myArgument){
console.log(
((myArgument.missingProberty)),
((myArgument)),
((nonExistingObject['XXX'])),
((this.myFoo))
);
return ((myArgument)) || 'somethingElse';
})
};
return myObject;
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
function require_saferjs(){
function replace(unsafe, params, body){
var matches = unsafe.match(/([\w\d_\$]+)([\[\.][\w\d_\$'"\[\]\.]+)?/i) || ['',''];
var name = matches[1];
var path = matches[2] || '';
var argument = params.indexOf(name);
if(argument>=0) name = 'arguments['+argument+']';
var literal = (name+path).replace(/\"/ig,'\\"');
var predicter = /^[.\(\[]/.test(path[0])
? 'typeof '+name+'=="undefined" && safer.beforeerror("'+name+'", "'+literal+'") && '+literal
: literal;
var resolver = '( '+predicter+' || safer.eval("'+literal+'",this,arguments))';
return body.replace(unsafe, resolver);
}
function generate(params, body){
var matches = body.match(/\(\(([\w\d_\$\[\]'"\.]+)\)\)/ig) || [];
for(var i=0;i<matches.length;i++){
var unsafe = matches[i];
body = replace(unsafe, params, body);
}
return new Function(body);
}
function safer(fn){
var source = fn.toString().replace(/\n/g, '');
var pattern = /function\s*\w*\s*\((.*)\)\s*{(.+)}\s*\;?\s*/i;
var matches = source.match(pattern) || ['',''];
var params = matches[1].replace(/\s+/ig,'').split(',');
var body = matches[2];
return generate(params, body);
}
safer.failsafe = true;
safer.beforeerror = function(variable, expression){
return safer.onbeforeerror && safer.onbeforeerror(variable, expression)
|| safer.failsafe ? !safer.failsafe : {};
};
safer.eval = function(source, context, arguments){
try{
return new Function("return "+source).apply(context, arguments);
}catch(e){
return;
}
}
return safer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment