Skip to content
This repository was archived by the owner on Dec 4, 2021. It is now read-only.

Commit 5e8749e

Browse files
Caleb HooverCaleb Hoover
Caleb Hoover
authored and
Caleb Hoover
committed
functions can now be sources if they return a source
1 parent 2d6fbc9 commit 5e8749e

File tree

1 file changed

+102
-46
lines changed

1 file changed

+102
-46
lines changed

check.js

Lines changed: 102 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ function(scope, node, ce) { // http.get
4949

5050
var r;
5151
if (ce.arguments[0]) {
52-
var file = scope.resolveExpression(node.arguments[0]);
53-
52+
var file;
53+
if (node.arguments[0].type == 'Literal')
54+
file = eval(scope.resolveExpression(node.arguments[0]));
55+
else {
56+
return;
57+
}
58+
59+
5460
scope.resolvePath(file, function (pkg) {
5561
if (!pkg)
5662
return;
@@ -96,12 +102,21 @@ Scope.prototype.track = function(variable) {
96102
var scope = this;
97103
var name = variable.id.name;
98104

99-
var value = this.resolveExpression(variable.init, function(extra) {
100-
scope.sources.push(name);
101-
scope.log('[SOURCE]'.red, variable, name);
102-
});
105+
var value = this.resolveExpression(variable.init);//, function(extra) {
106+
// scope.sources.push(name);
107+
// scope.log('[SOURCE]'.red, variable, name);
108+
// });
109+
if (value) {
110+
var resolved = this.resolve(value);
111+
if (resolved && typeof resolved == 'string') {
112+
if (this.isSource(resolved.name || resolved) || this.isSource(value.name || value)) {
113+
this.sources.push(name);
114+
this.log('[SOURCE]'.red, variable, name, value);
115+
}
116+
}
117+
}
103118

104-
scope.vars[name] = value;
119+
this.vars[name] = value;
105120

106121
if (flags.verbose && value)
107122
this.log('[VAR]', variable, name, value?value.raw || value:'');
@@ -110,20 +125,44 @@ Scope.prototype.track = function(variable) {
110125

111126
// returns a value for a variable if one exists
112127
Scope.prototype.resolve = function(name) {
113-
try {
114-
if (eval('this.vars.' + name))
128+
if (!name)
129+
return false;
130+
else if (typeof name != 'string')
131+
return false;
132+
if (name.indexOf('.') == -1) {
133+
if (get(this.vars, name)) {
115134
return eval('this.vars.' + name);
116-
else if (this.vars[name])
117-
return this.vars[name];
118-
else {
119-
var s = name.indexOf('.') == -1 ? name : name.split('.').slice(0,-1).join('.');
120-
return scope.vars[s] ? name.replace(s, scope.vars[s].raw||scope.vars[s]) : name;
121135
}
122-
} catch (e) {
123-
return name;
136+
} else {
137+
// console.log(121, name, !!get(this.vars, name)?get(this.vars, name):'');
138+
if (get(this.vars, name)) {
139+
return eval('this.vars.' + name);
140+
} else {
141+
var s = name.split('.');
142+
var r = this.resolve(s.slice(0,-1).join('.'));
143+
r = r.raw || r;
144+
// console.log(r + '.' + s.slice(-1));
145+
return r + '.' + s.slice(-1);
146+
}
124147
}
148+
149+
150+
return name;
125151
};
126152

153+
function get(json, name) {
154+
if (name.indexOf('.') == -1)
155+
return json[name];
156+
else {
157+
var s = name.split('.');
158+
try {
159+
return get(json[s[0]], s.slice(1).join('.'));
160+
} catch(e) {
161+
return false;
162+
}
163+
}
164+
}
165+
127166
Scope.prototype.resolveStatement = function(node) {
128167
var scope = this;
129168
switch (node.type) {
@@ -140,13 +179,12 @@ Scope.prototype.resolveStatement = function(node) {
140179

141180
var ceName = scope.resolve(ce.name);
142181

143-
144182
if (flags.verbose)
145-
this.log('[ CE ]', node, ceName, ce.raw);
183+
this.log('[CES]', node, ceName, ce.raw);
146184

147185
if (typeof ceName == 'string') {
148186
if (this.isSink(ceName)) {
149-
this.log('[SINK]'.red, node, ceName, ce.arguments?ce.arguments:'');
187+
this.log('[SINK]'.red, node, ce.raw, ceName);
150188
}
151189
}
152190

@@ -158,10 +196,10 @@ Scope.prototype.resolveStatement = function(node) {
158196
case 'AssignmentExpression':
159197
var assign = scope.resolveAssignment(node);
160198
var names = assign.names;
161-
var value = this.resolve(this.resolveExpression(assign.value, function() {
199+
var value = this.resolveExpression(assign.value, function() {
162200
scope.sources.push(names);
163201
scope.log('[SOURCE]'.red, node, names);
164-
}));
202+
});
165203

166204
names.forEach(function(name) {
167205
try {
@@ -198,10 +236,10 @@ Scope.prototype.resolveStatement = function(node) {
198236
case 'ForStatement':
199237
case 'WhileStatement':
200238
case 'CatchClause':
201-
this.traverse(node.body, this);
239+
this.traverse(node.body);
202240
break;
203241
case 'TryStatement':
204-
this.traverse(node.block, this);
242+
this.traverse(node.block);
205243
node.handlers.forEach(function (h) {
206244
scope.resolveStatement(h);
207245
});
@@ -233,15 +271,16 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
233271
var scope = this;
234272
switch (right.type) {
235273
case 'Literal':
236-
return right.value;
274+
return right.raw;
237275
case 'Identifier':
238276
// if variable is being set to a bad variable, mark it too as bad
239277

240278
var resolved = scope.resolve(right.name);
241-
if (resolved && typeof resolved == 'String') {
279+
if (resolved && typeof resolved == 'string') {
242280
if (scope.isSource(resolved.name)) {
243-
if (isSourceCB)
281+
if (isSourceCB) {
244282
isSourceCB();
283+
}
245284
}
246285
}
247286
return right.name;
@@ -254,32 +293,33 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
254293
climb(right).forEach(function (i) {
255294
if (i.type == 'Identifier') {
256295
if (scope.isSource(i.name)) {
257-
if (isSourceCB)
296+
if (isSourceCB) {
258297
isSourceCB(i.name);
298+
}
259299
}
260300
}
261301
});
262302
return {};
263303
case 'CallExpression':
264304
var ce = scope.resolveCallExpression(right);
265305

266-
if (flags.verbose)
267-
this.log('[CE]', right, ce.raw);
268306

269307
if (!ce.name)
270308
return ce;
271309
if (typeof ce.name != 'string')
272310
return;
273311

274-
275312
var ceName = scope.resolve(ce.name);
313+
314+
if (flags.verbose)
315+
this.log('[CE]', right, ceName, ce.raw);
276316

277-
if (scope.isSource(ceName || ce.name)) {
278-
if (isSourceCB)
279-
isSourceCB(ceName);
280-
}
317+
if (ceName && typeof ceName == 'string') {
318+
if (scope.isSource(ceName)) {
319+
if (isSourceCB)
320+
isSourceCB(ceName);
321+
}
281322

282-
if (typeof ceName == 'string') {
283323
if (this.isSink(ceName)) {
284324
this.log('[SINK]'.red, right, ceName, ce.arguments?ce.arguments:'');
285325
}
@@ -288,7 +328,7 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
288328
return ce;
289329
case 'MemberExpression':
290330
var me = scope.resolveMemberExpression(right);
291-
if (typeof me == "string" && scope.isSource(me)) {
331+
if (typeof me == 'string' && scope.isSource(me)) {
292332
if (isSourceCB)
293333
isSourceCB();
294334
}
@@ -297,7 +337,6 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
297337
return scope.resolveObjectExpression(right);
298338
case 'FunctionExpression': // functions
299339
var fe = scope.resolveFunctionExpression(right);
300-
traverse(fe.body, fe.scope);
301340
return fe;
302341
}
303342
};
@@ -410,6 +449,7 @@ Scope.prototype.resolveObjectExpression = function(node) {
410449
};
411450

412451
Scope.prototype.resolveFunctionExpression = function(node) {
452+
var scope = this;
413453
var fe = {
414454
name: node.id ? node.id.name : '',
415455
params: _.pluck(node.params, 'name'),
@@ -420,18 +460,32 @@ Scope.prototype.resolveFunctionExpression = function(node) {
420460
for (var i in fe.params) {
421461
fe.scope.addVar(fe.params[i], undefined);
422462
}
463+
fe.scope.traverse(fe.body, function(node) {
464+
var arg = scope.resolveExpression(node.argument);
465+
var resolved = scope.resolve(arg);
466+
if (resolved && typeof resolved == 'string') {
467+
if (scope.isSource(resolved.name || resolved) || scope.isSource(arg.name || arg)) {
468+
if (fe.name)
469+
scope.sources.push(fe.name);
470+
scope.log('[RETURN]'.red, node, fe.name, arg, resolved);
471+
}
472+
}
473+
});
423474

424475
return fe;
425476
};
426477

427478
// Traverses an array of statments.
428-
Scope.prototype.traverse = function(ast) {
479+
Scope.prototype.traverse = function(ast, returnCB) {
429480
var scope = this;
430481
if (ast.type == 'BlockStatement'){
431482
(ast.body || [ast]).forEach(function (node) {
432483
if (node.type == 'ExpressionStatement')
433484
node = node.expression;
434485
scope.resolveStatement(node);
486+
if (returnCB && node.type == 'ReturnStatement') {
487+
returnCB(node);
488+
}
435489
});
436490
} else {
437491
// ast is a single statement so resolve it instead
@@ -482,7 +536,9 @@ Scope.prototype.isSource = function(name) {
482536
Scope.prototype.isSink = function(name) {
483537
if (typeof name != 'string')
484538
return false;
539+
// console.log(name);
485540
for (var i in this.sinks) {
541+
// console.log('\t', this.sinks[i], name.search(this.sinks[i]));
486542
if (name.search(this.sinks[i]) === 0) {
487543
return true;
488544
}
@@ -541,11 +597,11 @@ module.exports.pos = pos = function(node) {
541597
return node.loc ? String(node.loc.start.line) : "-1";
542598
};
543599

544-
function get(json, key) {
545-
keys = key.split('.').length();
546-
if (keys.length() == 1)
547-
return json[key];
548-
else {
549-
return get(json[keys[0]], keys.slice(1));
550-
}
551-
}
600+
// function get(json, key) {
601+
// keys = key.split('.');
602+
// if (keys.length == 1)
603+
// return json[key];
604+
// else {
605+
// return get(json[keys[0]], keys.slice(1));
606+
// }
607+
// }

0 commit comments

Comments
 (0)