├── tests ├── stage17 │ └── plugin17.js ├── stage11 │ ├── plugin11_1.js │ └── plugin11.js ├── stage01 │ └── plugin1.js ├── stage30 │ └── plugin30.js ├── stage06 │ ├── plugin6_1.js │ └── plugin6_2.js ├── tests_node.js ├── stage02 │ └── plugin2.js ├── stage07 │ └── plugin7.js ├── stage09 │ └── plugin9.js ├── stage12 │ └── plugin12.js ├── stage03 │ └── plugin3.js ├── stage15 │ ├── plugin15_good.js │ └── plugin15_bad.js ├── stage10 │ └── plugin10.js ├── stage23 │ └── plugin23.js ├── stage04 │ └── plugin4.js ├── stage26 │ └── plugin26.js ├── stage27 │ └── plugin27.js ├── tests_web.html ├── stage21 │ └── plugin21.js ├── stage19 │ └── plugin19.js ├── stage31 │ └── plugin31.js ├── stage16 │ └── plugin16.js ├── stage05 │ └── plugin5.js ├── stage28 │ └── plugin28.js ├── stage25 │ └── plugin25.js ├── stage08 │ └── plugin8.js ├── stage29 │ └── plugin29.js ├── stage13 │ └── plugin13.js ├── stage24 │ └── plugin24.js ├── stage22 │ └── plugin22.js ├── stage20 │ └── plugin20.js ├── stage32 │ └── plugin32.js ├── lighttest.js └── tests.js ├── lib ├── _frame.html ├── _pluginWebIframe.js ├── _pluginCore.js ├── _pluginWebWorker.js ├── _frame.js ├── _pluginNode.js ├── _JailedSite.js └── jailed.js ├── demos ├── web │ ├── banner │ │ ├── bad.png │ │ ├── good.png │ │ ├── empty.png │ │ ├── readme.md │ │ ├── banner.js │ │ ├── application.js │ │ ├── index.html │ │ └── style.css │ ├── console │ │ ├── bg.png │ │ ├── readme.md │ │ ├── index.html │ │ ├── plugin.js │ │ ├── style.css │ │ └── application.js │ ├── process │ │ ├── bg.png │ │ ├── scroll.png │ │ ├── plugin.js │ │ ├── index.html │ │ ├── style.css │ │ ├── refresh.svg │ │ └── application.js │ └── circle │ │ ├── readme.md │ │ ├── plugin.js │ │ ├── index.html │ │ ├── application.js │ │ └── style.css └── node │ ├── fs │ ├── log.txt │ ├── readme.md │ ├── start.js │ └── plugin.js │ └── timeout │ ├── plugin.js │ ├── readme.md │ └── start.js ├── bower.json ├── package.json ├── LICENSE └── README.md /tests/stage17/plugin17.js: -------------------------------------------------------------------------------- 1 | auaa } u((uu& -------------------------------------------------------------------------------- /lib/_frame.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/stage11/plugin11_1.js: -------------------------------------------------------------------------------- 1 | application.disconnect(); -------------------------------------------------------------------------------- /tests/stage01/plugin1.js: -------------------------------------------------------------------------------- 1 | 2 | application.remote.callMe(); 3 | -------------------------------------------------------------------------------- /tests/stage30/plugin30.js: -------------------------------------------------------------------------------- 1 | 2 | application.whenConnected('something'); -------------------------------------------------------------------------------- /demos/web/banner/bad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/banner/bad.png -------------------------------------------------------------------------------- /demos/web/banner/good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/banner/good.png -------------------------------------------------------------------------------- /demos/web/console/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/console/bg.png -------------------------------------------------------------------------------- /demos/web/process/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/process/bg.png -------------------------------------------------------------------------------- /tests/stage06/plugin6_1.js: -------------------------------------------------------------------------------- 1 | application.setInterface({square: function(val, cb){ cb(val*val); } }); -------------------------------------------------------------------------------- /demos/web/banner/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/banner/empty.png -------------------------------------------------------------------------------- /demos/web/process/scroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvd/jailed/HEAD/demos/web/process/scroll.png -------------------------------------------------------------------------------- /tests/stage06/plugin6_2.js: -------------------------------------------------------------------------------- 1 | application.setInterface({square: function(val, cb){ cb(val*val); } }); 2 | -------------------------------------------------------------------------------- /tests/tests_node.js: -------------------------------------------------------------------------------- 1 | require('./lighttest.js'); 2 | jailed = require('../lib/jailed.js'); 3 | require('./tests.js'); 4 | -------------------------------------------------------------------------------- /tests/stage02/plugin2.js: -------------------------------------------------------------------------------- 1 | var cb = function(result) { 2 | application.remote.report(result); 3 | } 4 | 5 | application.remote.square(2, cb); -------------------------------------------------------------------------------- /tests/stage07/plugin7.js: -------------------------------------------------------------------------------- 1 | var api = { 2 | square : function(val, cb) {cb(val*val);} 3 | }; 4 | 5 | 6 | application.setInterface(api); 7 | -------------------------------------------------------------------------------- /tests/stage09/plugin9.js: -------------------------------------------------------------------------------- 1 | var finalize = function() { 2 | application.remote.done(); 3 | } 4 | 5 | application.remote.checkAttempt(finalize); -------------------------------------------------------------------------------- /tests/stage12/plugin12.js: -------------------------------------------------------------------------------- 1 | var api = { 2 | square: function(val, cb) { 3 | cb(val*val); 4 | } 5 | } 6 | 7 | application.setInterface(api); -------------------------------------------------------------------------------- /tests/stage03/plugin3.js: -------------------------------------------------------------------------------- 1 | 2 | var api = { 3 | square : function(val, cb) { 4 | cb(val*val); 5 | } 6 | }; 7 | 8 | application.setInterface(api); 9 | -------------------------------------------------------------------------------- /tests/stage15/plugin15_good.js: -------------------------------------------------------------------------------- 1 | 2 | var api = { 3 | square : function(val, cb) { 4 | cb(val*val); 5 | } 6 | } 7 | 8 | application.setInterface(api); -------------------------------------------------------------------------------- /demos/node/fs/log.txt: -------------------------------------------------------------------------------- 1 | New message added by the plugin on Wed Aug 27 2014 01:51:07 GMT+0200 (CEST) 2 | New message added by the plugin on Sun Sep 21 2014 14:16:24 GMT+0200 (CEST) 3 | -------------------------------------------------------------------------------- /tests/stage15/plugin15_bad.js: -------------------------------------------------------------------------------- 1 | 2 | var api = { 3 | infinite: function(cb) { 4 | while (true) {}; 5 | cb(); 6 | } 7 | } 8 | 9 | application.setInterface(api); 10 | -------------------------------------------------------------------------------- /tests/stage11/plugin11.js: -------------------------------------------------------------------------------- 1 | var api = { 2 | square : function(val, cb) { cb(val*val); }, 3 | killYourself : function() { application.disconnect(); } 4 | } 5 | 6 | application.setInterface(api); 7 | 8 | -------------------------------------------------------------------------------- /tests/stage10/plugin10.js: -------------------------------------------------------------------------------- 1 | 2 | var cb1 = function(result) { 3 | var cb2 = function() { 4 | application.remote.done(); 5 | } 6 | 7 | application.remote.report(result, cb2); 8 | } 9 | 10 | 11 | application.remote.getNum(cb1); -------------------------------------------------------------------------------- /tests/stage23/plugin23.js: -------------------------------------------------------------------------------- 1 | 2 | var api = { 3 | callback: function(num, cb0, cb1) { 4 | if (num == 0) { 5 | cb0(); 6 | } else { 7 | cb1(); 8 | } 9 | } 10 | } 11 | 12 | application.setInterface(api); -------------------------------------------------------------------------------- /tests/stage04/plugin4.js: -------------------------------------------------------------------------------- 1 | var api = { 2 | squareDelayed : function(val, cb) { 3 | var cb1 = function() { 4 | cb(val*val); 5 | } 6 | 7 | application.remote.wait(cb1); 8 | } 9 | }; 10 | 11 | application.setInterface(api); 12 | -------------------------------------------------------------------------------- /tests/stage26/plugin26.js: -------------------------------------------------------------------------------- 1 | var api = { 2 | squareDelayed: function(val, cb) { 3 | application.remote.wait( 4 | function() { 5 | cb(val*val); 6 | } 7 | ); 8 | } 9 | }; 10 | 11 | application.setInterface(api); -------------------------------------------------------------------------------- /demos/web/circle/readme.md: -------------------------------------------------------------------------------- 1 | # Dangling Circle demo 2 | 3 | This example demonstrates how to use a plugin to easily perform a 4 | heavy calculation in a separate therad. 5 | 6 | Watch this demo online: 7 | 8 | [https://asvd.github.io/jailed/demos/web/circle/](https://asvd.github.io/jailed/demos/web/circle/) 9 | -------------------------------------------------------------------------------- /demos/web/console/readme.md: -------------------------------------------------------------------------------- 1 | # Console demo 2 | 3 | This example demonstrates the usage of a plugin for evaluating a 4 | potentially untrusted code submitted by the user 5 | 6 | Watch this demo online: 7 | 8 | [https://asvd.github.io/jailed/demos/web/console/](https://asvd.github.io/jailed/demos/web/console/) 9 | -------------------------------------------------------------------------------- /tests/stage27/plugin27.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var init = function() { 4 | var notYetCalled = true; 5 | var cb = function() { 6 | application.remote.check(notYetCalled); 7 | notYetCalled = false; 8 | } 9 | 10 | application.remote.callme(cb, cb); 11 | } 12 | 13 | application.whenConnected(init); 14 | -------------------------------------------------------------------------------- /demos/web/banner/readme.md: -------------------------------------------------------------------------------- 1 | # Banner demo 2 | 3 | This example demonstrates how a third-party partner's library 4 | (`banner.js`) may be used to safely manipulate on the part of an 5 | application. 6 | 7 | Watch this demo online: 8 | 9 | [https://asvd.github.io/jailed/demos/web/banner/](https://asvd.github.io/jailed/demos/web/banner/) 10 | -------------------------------------------------------------------------------- /tests/tests_web.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
';
37 | var code = el.code.innerText;
38 | var input = el.input_data.innerText;
39 |
40 | var plugin = new jailed.Plugin(path+'plugin.js');
41 | var process = function() {
42 | var displayResult = function(result) {
43 | if (result.error) {
44 | el.output_data.innerHTML =
45 | ''+result.error + '';
46 | } else {
47 | el.output_data.innerHTML = stringify(result.output);
48 | }
49 | plugin.disconnect();
50 | }
51 |
52 | plugin.remote.process(input, code, displayResult);
53 | }
54 |
55 | plugin.whenConnected(process);
56 | }
57 |
58 |
59 | // converts an object into a string
60 | function stringify(object) {
61 | var result;
62 |
63 | if (typeof object == 'undefined') {
64 | result = 'undefined';
65 | } else if (object === null) {
66 | result = 'null';
67 | } else {
68 | result = JSON.stringify(object) || object.toString();
69 | }
70 |
71 | return result;
72 | }
73 |
74 |
75 |
76 | // removes spaces from the end of the strings
77 | function trim_tails(string) {
78 | var arr = string.split('\n');
79 |
80 | for (var i = 0; i < arr.length; i++) {
81 | arr[i] = arr[i].replace(/[\s\uFEFF\xA0]+$/g, '');
82 | }
83 |
84 | return arr.join('\n');
85 | }
86 |
87 | // fills the processing code textarea with initial content
88 | function fill_code() {
89 | var code = trim_tails([
90 | 'function(input) { ',
91 | ' // bubble sorting the input array ',
92 | ' ',
93 | ' // switches the two elems if needed ',
94 | ' // returns true if switched ',
95 | ' function switchEls(idx) { ',
96 | ' var switched = false; ',
97 | ' if (input[idx] < input[idx-1]) { ',
98 | ' var tmp = input[idx]; ',
99 | ' input[idx] = input[idx-1]; ',
100 | ' input[idx-1] = tmp; ',
101 | ' switched = true; ',
102 | ' } ',
103 | ' return switched; ',
104 | ' } ',
105 | ' ',
106 | ' var switched; ',
107 | ' do { ',
108 | ' switched = false; ',
109 | ' for (var i = 1; i < input.length; i++) { ',
110 | ' switched |= switchEls(i); ',
111 | ' } ',
112 | ' } while(switched); ',
113 | ' ',
114 | ' return input; ',
115 | '} ',
116 | ' ',
117 | ' '
118 | ].join('\n'));
119 |
120 | el.code.container.innerHTML = code;
121 | }
122 |
123 |
124 | function init() {
125 | el.button_regen_input.onclick = regen_input;
126 | el.button_process.onclick = process;
127 | fill_code();
128 | regen_input();
129 |
130 | // caching
131 | var plugin = new jailed.Plugin(path+'plugin.js');
132 | plugin.whenConnected(function(){plugin.disconnect();});
133 |
134 | el.code.container.focus();
135 | }
136 |
137 | window.addEventListener("load", init, false);
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/demos/web/console/application.js:
--------------------------------------------------------------------------------
1 |
2 | // component shortcuts
3 | var el = {};
4 | var list = [
5 | 'terminalWrap', 'command', 'line', 'terminal', 'indicator'
6 | ];
7 |
8 | for (var i = 0; i < list.length; i++){
9 | el[list[i]] = document.getElementById(list[i]);
10 | }
11 |
12 |
13 | // newer elements template
14 | var sample = document.createElement('div');
15 |
16 |
17 | // command history
18 | var hist = {
19 | _list: [''],
20 | _pos: 0,
21 |
22 | push: function(val) {
23 | var last = this._list.length-1;
24 |
25 | // prevent duplicates
26 | if (this._list[last-1] !== val) {
27 | this._list[last] = val;
28 | this._list.push('');
29 | }
30 |
31 | this._pos = this._list.length-1;
32 | },
33 |
34 | set: function(val) {
35 | if (this._pos >= this._list.length-1) {
36 | this._list[this._pos] = val;
37 | }
38 | },
39 |
40 | next: function() {
41 | if (typeof this._list[this._pos+1] != 'undefined') {
42 | this._pos++;
43 | }
44 |
45 | return this._list[this._pos];
46 | },
47 |
48 | prev: function() {
49 | if (typeof this._list[this._pos-1] != 'undefined') {
50 | this._pos--;
51 | }
52 |
53 | return this._list[this._pos];
54 | }
55 | };
56 |
57 |
58 | // command line keypress handlers
59 | el.line.onkeydown = function(e) {
60 | switch (e.keyCode) {
61 | case 38: // up arrow
62 | var val = hist.prev();
63 | el.line.value = val;
64 | el.line.setSelectionRange(val.length, val.length);
65 | e.preventDefault();
66 | break;
67 |
68 | case 40: // down arrow
69 | var val = hist.next();
70 | el.line.value = val;
71 | el.line.setSelectionRange(val.length, val.length);
72 | e.preventDefault();
73 | break;
74 |
75 | case 13: // enter
76 | var val = el.line.value;
77 | if (val) {
78 | hist.push(val);
79 | el.line.value = '';
80 | submit(val);
81 | }
82 | break;
83 | }
84 | }
85 |
86 |
87 | el.line.onkeyup = function(e) {
88 | switch (e.keyCode) {
89 | case 38: // up arrow
90 | case 40: // down arrow
91 | case 13: // enter
92 | break;
93 |
94 | default:
95 | // update current history entry
96 | hist.set(el.line.value);
97 | break;
98 | }
99 | }
100 |
101 |
102 | // sends the input to the plugin for evaluation
103 | var submit = function(code) {
104 | animateSubmit(code);
105 |
106 | // postpone the evaluation until the plugin is initialized
107 | plugin.whenConnected(
108 | function() {
109 | if (requests == 0) {
110 | startLoading();
111 | }
112 |
113 | requests++;
114 | plugin.remote.run(code);
115 | }
116 | );
117 | }
118 |
119 |
120 | // animates input submission
121 | var animateSubmit = function(code) {
122 | var anim = sample.cloneNode(false);
123 | anim.setAttribute('class', 'commandTextAnimated');
124 | anim.innerHTML = escape(code);
125 |
126 | el.command.appendChild(anim);
127 |
128 | anim.offsetHeight;
129 | anim.style.top = -20;
130 | anim.style.opacity = .6;
131 |
132 | setTimeout(
133 | function() {
134 | el.command.removeChild(anim);
135 | }, 500
136 | );
137 |
138 | }
139 |
140 |
141 | // prepares the string to be printed on the terminal
142 | var escape = function(msg) {
143 | return msg.
144 | replace(/&/g,'&').
145 | replace(//g,'>').
147 | replace(/\n/g, '