diff --git a/JavaScript/application.js b/JavaScript/application.js index 8f018b8..bbc97ab 100644 --- a/JavaScript/application.js +++ b/JavaScript/application.js @@ -4,16 +4,32 @@ // of a sample application to be executed in the sandboxed context by // another pice of code from `framework.js`. Read README.md for tasks. -const fs = require('fs'); -const net = require('net'); +const o = new Map ([ + [ ((field) => field)('field'), 'hello' ], + [ 'field2', new Object({ field1: 10, field2: '20' }) ], + [ (fn => fn)('fn'), new Function('a, b', 'return a + b') ], + [ (function arr(name){return name})('arr'), new Array(1,2,3) ], + [ ['boolean'], new Boolean(new Set() instanceof Object).valueOf() ], + //[ (async (n) => {return n})('async').then(console.log), new Promise(resolve => resolve()) ] +]) // Print from the global context of application module -console.log('From application global context'); -console.dir({ fs, net }, { depth: 1 }); -console.dir({ global }, { depth: 1 }); -console.dir({ api }, { depth: 2 }); +const fn = new Function('a,s', 'return a + s'); +// require module fs and util +api.console.log(api.util.inspect(o)); + +api.console.log('From global context'); +require('fs'); +require('util'); + +// exported function module.exports = () => { - // Print from the exported function context - console.log('From application exported function'); -}; + api.timers.setTimeout(() => api.console.log('From exported timeout'), 1000) + api.timers.setInterval(() => api.console.log('From exported timeout'), 2000) +} + +// usage of timers +api.timers.setTimeout(() => { + api.console.log('From timer'); +}, 1000) diff --git a/JavaScript/framework.js b/JavaScript/framework.js index 6bdafde..11721b6 100644 --- a/JavaScript/framework.js +++ b/JavaScript/framework.js @@ -4,67 +4,76 @@ // appication runtime, load an application code and passes a sandbox into app // as a global context and receives exported application interface -const PARSING_TIMEOUT = 1000; -const EXECUTION_TIMEOUT = 5000; - // The framework can require core libraries -const fs = require('fs'); -const vm = require('vm'); -const timers = require('timers'); -const events = require('events'); +global.api = {}; +api.fs = require('fs'); +api.vm = require('vm'); +api.util = require('util'); + +function Req() {}; +// #6 +Req.prototype.fn = function (module) { + console.log('ModuleName: ' + module); + console.log('Time: ' + new Date()); + require(module); +} +// #4 +Req.prototype.wrapped = function (path, fn) { + const wrapped = item => { + console.log('ApplicationName: ' + path); + console.log('Time: ' + new Date()); + fn(item); + }; + return wrapped; +} +// #8 +Req.prototype.count = function(f) { + console.log(f.length); + console.log(f.toString()); +} -// Create a hash and turn it into the sandboxed context which will be -// the global context of an application -const context = { - module: {}, console, - require: name => { - if (name === 'fs') { - console.log('Module fs is restricted'); - return null; +const runSandboxed = path => { + const context = { + module: {}, + require: new Req().fn, + api: { + console: { log: new Req().wrapped(path, console.log) }, // #1 + timers: { setTimeout, setInterval }, + fs: api.fs, + util: api.util // #2 + }, } - return require(name); - } -}; -context.global = context; -const sandbox = vm.createContext(context); + context.global = context; + const sandbox = api.vm.createContext(context); + // Read an application source code from the file + api.fs.readFile(path, (err, src) => { + // We need to handle errors here -// Prepare lambda context injection -const api = { timers, events }; + // Run an application in sandboxed context + const script = new api.vm.Script(src); + // #3 + if (process.argv[2] === path || path === 'application.js') script.runInNewContext(sandbox); -// Read an application source code from the file -const fileName = './application.js'; -fs.readFile(fileName, 'utf8', (err, src) => { - // We need to handle errors here + const exported = sandbox.module.exports; + console.log(exported); - // Wrap source to lambda, inject api - src = `api => { ${src} };`; + //count args of exported function and print input code + if (typeof exported === 'function') { new Req().count(exported); exported() } - // Run an application in sandboxed context - let script; - try { - script = new vm.Script(src, { timeout: PARSING_TIMEOUT }); - } catch (e) { - console.dir(e); - console.log('Parsing timeout'); - process.exit(1); - } + // print type of exported inside items, (instance of Map) + // console.log(exported) + // exported instanceof Map --- false + else if (new Map([]) instanceof Map) { // #7 + for (const [key, val] of exported.entries()) { + console.log(key + ': ' + typeof val); + }; + } - try { - const f = script.runInNewContext(sandbox, { timeout: EXECUTION_TIMEOUT }); - f(api); - const exported = sandbox.module.exports; - console.dir({ exported }); - } catch (e) { - console.dir(e); - console.log('Execution timeout'); - process.exit(1); - } + // We can access a link to exported interface from sandbox.module.exports + // to execute, save to the cache, print to console, etc. - // We can access a link to exported interface from sandbox.module.exports - // to execute, save to the cache, print to console, etc. -}); + }) +} -process.on('uncaughtException', err => { - console.log('Unhandled exception: ' + err); -}); +runSandboxed('application.js');