Skip to content

Instantly share code, notes, and snippets.

@shimondoodkin
Created December 23, 2010 00:09
Show Gist options
  • Select an option

  • Save shimondoodkin/752345 to your computer and use it in GitHub Desktop.

Select an option

Save shimondoodkin/752345 to your computer and use it in GitHub Desktop.
this is a follow up to my previous post about run in same context bug/future that contexts are not referenced when using multiple times runInNewContext with the same context - a solution is test 3 here
//licensed public domain
Array.prototype.next=function(){var z=this.shift();if(z)z();};
var simpleasync;
function test1()
{
//test1.js
console.log("\r\n\r\n this test should fail: \r\n");
var sandbox = { setTimeout: setTimeout, console:console};
var myscript=0;
function run_scripts_in_same_context(text)
{
process.binding('evals').Script.runInNewContext(text,sandbox,'myfile'+(myscript++)+'.js');
}
run_scripts_in_same_context('var x="1"; function showx(){console.log("x="+x);} setTimeout(function(){showx();},100)');//edit now, show later
run_scripts_in_same_context('x="5"; showx();'); //edit now and show now, this shows first.
console.log("The last x should be 5, If it is 1 then the contexts are not referenced");
// end test1
setTimeout(function(){simpleasync.next()},200);
}
function test2()
{
//test2.js
console.log("\r\n\r\nThis test should be successful: \r\n");
var sandbox = { setTimeout: setTimeout, console:console, runInThisContext:require('vm').runInThisContext };
function code()
{
var ScriptId=0;
function evalCode(code,name)
{
if(name)
runInThisContext(code,name);
else
runInThisContext(code,'myfile'+(ScriptId++)+'.js');
}
}
code = code.toString() ;
code = code.substring( code.indexOf('{')+1 , code.lastIndexOf('}')-1 );
require('vm').runInNewContext(code,sandbox);
var fs=require('fs');
sandbox.evalCode('var x="1"; function showx(){console.log("x="+x);} setTimeout(function(){showx();},100)');
sandbox.evalCode('x="5"; showx();');
console.log("The last x should be 5. If it is 1 then the contexts are not referenced");
//end test2
setTimeout(function(){ simpleasync.next(); },200)
}
function test3()
{
//test3.js
console.log("\r\n\r\n This test tries break out the sandbox, should be errors below: \r\n");
var sandbox = { setTimeout: setTimeout, console:console, runInThisContext:require('vm').runInThisContext };
function code()
{
var ScriptId=0;
function evalCode(code,name)
{
try{
if(typeof name!==undefined)
runInThisContext(code,name);
else
runInThisContext(code,'myfile'+(ScriptId++)+'.js');
}
catch(e)
{
console.log('-------evalCode--------\r\n'+e.stack+'\r\n-----------------------\r\n');
}
}
}
code = code.toString() ;
code = code.substring( code.indexOf('{')+1 , code.lastIndexOf('}')-1 );
require('vm').runInNewContext(code,sandbox);
var fs=require('fs');
sandbox.evalCode(" try{console.log(fs);}catch(e){console.log('Can\\'t find fs');} ");
sandbox.evalCode(" try{console.log(require('fs'));}catch(e){console.log('Can\\'t find require()');} ");
sandbox.evalCode(" console.log(require('fs')) ");
////test3 end
simpleasync.next();
}
function test4()
{
//test4.js
console.log('the function runInThisContext can\'t comunicate with outside world variables, but it can return a variable:')
console.log('this test expected to fail for the current state of runInThisContext:');
var window={}
process.binding('evals').Script.runInThisContext('console.log(typeof window=="undefined"?"window is undefined":window)', 'myfile.js');
////test4 end
simpleasync.next();
}
function test5()
{
//test5.js
console.log('The solution: hook into the global object (This test should be successful)')
var Script=process.binding('evals').Script;
var hook = Script.runInThisContext('global', 'myfile.js');
console.log("hook:"); console.log(hook);
hook.window={'test5':'it works'};
Script.runInThisContext(' console.log("window:"); console.log(window) ', 'myfile.js');
////test5 end
simpleasync.next();
}
function test6()
{
//test6.js
console.log("\r\n\r\n This test will runcode with a window as global object: \r\n");
var Script= process.binding('evals').Script;
var sandbox = { setTimeout: setTimeout, console:console, runInThisContext: Script.runInThisContext };
function code()
{
var ScriptId=0;
function evalCode(code,name)
{
try{
if(typeof name!=='undefined')
runInThisContext('with(window){'+code+'}',name);
else
runInThisContext('with(window){'+code+'}','myfile'+(ScriptId++)+'.js');
}
catch(e)
{
console.log('-------evalCode--------\r\n'+e.stack+'\r\n-----------------------\r\n');
}
}
}
code = code.toString() ;
code = code.substring( code.indexOf('{')+1 , code.lastIndexOf('}')-1 );
Script.runInNewContext(code,sandbox);
var hook=sandbox.runInThisContext('global')
var window={foo:'bar'}
hook.window=window;
sandbox.evalCode(" console.log(foo) ");
window.foo='baz';
sandbox.evalCode(" console.log(foo) ");
sandbox.evalCode(" moo=1 ");
sandbox.evalCode(" console.log(window) ");
sandbox.evalCode(" console.log('typeof require='+(typeof require)) ");
////test6 end
simpleasync.next();
}
function test7()
{
//test7.js
console.log('The folowing i s acopy of code fon mode js i had to dig little deeper to find it (undocumented) I wish they told me about it in the mailing list.')
//Context is an empty object with a classname of Context
//also context has a native static method getV8Context to return a presistent variable "_context".
assert = require("assert");
var Script = require('vm').Script;
console.log('run in a new empty context');
var context = Script.createContext(); //
var result = Script.runInContext('"passed";', context);
assert.equal('passed', result);
console.log('create a new pre-populated context');
context = Script.createContext({'foo': 'bar', 'thing': 'lala'});
assert.equal('bar', context.foo);
assert.equal('lala', context.thing);
console.log('test updating context');
result = Script.runInContext('var foo = 3;', context);
assert.equal(3, context.foo);
assert.equal('lala', context.thing);
////test7 end
simpleasync.next();
}
function test8()
{
//test8.js
console.log('lets try to derive a Context')
//process.binding('evals').Context
//process.binding('evals').Script.runInContext(code,window,filename)
//process.binding('evals').Script.CreateContext(fromobject) // just copies staff from the object to the context
console.log(process.binding('evals').Context) // context exists yey found it
/*
inheritance from a native object
http://www.mail-archive.com/v8-users@googlegroups.com/msg02170.html
function Derived(args) {
var base = new Base();
base.__proto__ = Derived.prototype;
return base;
}
Derived.prototype = {__proto__: Base.prototype, constructor: Derived };
*/
//
var Context=process.binding('evals').Context;
function DOMWindow(args) {
var base = new Context();
base.__proto__ = DOMWindow.prototype;
return base;
}
DOMWindow.prototype = {__proto__: Context.prototype, constructor: DOMWindow };
var window=new DOMWindow();
var Script=process.binding('evals').Script;
Script.runInContext('x=1',window) // test the derived context
console.log(window)
////test8 end
simpleasync.next();
}
simpleasync=[/*test1,test2,test3,test4,test5,test6,test7*/ test8];
simpleasync.next();
// nano ~/node-v0.3.1/src/node_script.cc
@shimondoodkin

Copy link
Copy Markdown
Author

Output:

 this test should fail:

x=1
The last x should be 5, If it is 1 then the contexts are not referenced
x=1


This test should be successful:

x=5
The last x should be 5. If it is 1 then the contexts are not referenced
x=5


 This test tries break out the sandbox, should be errors below:

Can't find fs
Can't find require()
-------evalCode--------
ReferenceError: require is not defined
    at undefined:1:14
    at Object.evalCode (evalmachine.<anonymous>:7:4)
    at test3 (/home/rakia/www/misc.dev.pijimi.com/testsendbox.js:82:9)
    at /home/rakia/www/misc.dev.pijimi.com/testsendbox.js:3:64
    at Object._onTimeout (/home/rakia/www/misc.dev.pijimi.com/testsendbox.js:49:26)
    at Timer.callback (timers.js:93:39)
-----------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment