1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
var acorn = require('acorn/dist/acorn_loose');
var walk = require("acorn/dist/walk");
var acorn_base = require("acorn");
/**
* Loop over a function and get a list of things being called.
*
* Tests to see if the function calls itself.
*
* Note: If it is an anonmyous function, recursion isn't possible.
*
*/
function get_function_names(input_node_src,scope){
var func_name = "";
var flag = true;
// The name of the function can't appear anywhere.
// No bracket suffix notation either.
console.log("Searching for identifier '"+scope+"' in this code:");
console.log(input_node_src);
var tokens = acorn_base.tokenizer(input_node_src);
var toke = tokens.getToken();
while(toke.type != acorn_base.tokTypes.eof){
if(toke.type.label == "name" && scope == toke.value){
return true;
}
toke = tokens.getToken();
}
return false;
}
window.onload = function () {
document.getElementById("parse").addEventListener("click",function(){
var res = true;
var script = document.getElementById("input").value;
var ast = acorn.parse_dammit(script).body[0];
document.getElementById("output").innerHTML = JSON.stringify(ast, null, "\t"); // Indented with tab
var flag = false;
var amtloops = 0;
// COUNTS LOOPS AND CONDITIONALS
walk.simple(ast, {
ForInStatement(node){
if(amtloops > 3){return;}
console.log("ForInStatement");
amtloops++;
},
ForStatement(node){
if(amtloops > 3){return;}
console.log("ForStatement");
amtloops++;
},
DoWhileStatement(node){
if(amtloops > 3){return;}
console.log("DoWhileStatement");
amtloops++;
},
WhileStatement(node){
if(amtloops > 3){return;}
console.log("WhileStatement");
amtloops++;
},
IfStatement(node){
if(amtloops > 3){return;}
console.log("IfStatement");
amtloops++;
},
SwitchStatement(node){
if(amtloops > 3){return;}
console.log("SwitchStatement");
amtloops++;
}
});
if(amtloops > 3){
console.log("%c NONTRIVIAL: Too many loops/conditionals.","color:red");
// TODO: return here
}
// DETECT RECURSION
var nontrivial = false;
walk.simple(ast, {
CallExpression(node){
if(nontrivial == true){
return;
}
test_function_name(node.callee.name);
}
});
if(nontrivial == true){
console.log("%c NONTRIVIAL: Recursion detected.","color:red");
res = false;// TODO: return here
}
document.getElementById("output").innerHTML = res + "\n\n" + document.getElementById("output").innerHTML;
});
}
|