Initial commit

master
Sven Slootweg 7 years ago
commit 2f1d820509

1
.gitignore vendored

@ -0,0 +1 @@
node_modules

@ -0,0 +1,57 @@
'use strict';
const blessed = require("blessed");
const visualizeAST = require("./lib/ast/visualize");
const esprima = require("esprima");
const util = require("util");
const fs = require("fs");
const markCode = require("./lib/ast/render/mark-code");
let code = fs.readFileSync("./test/1.js").toString();
let _testdata = esprima.parse(code, {
range: true,
loc: true
});
let ast = visualizeAST(_testdata);
let screen = blessed.screen({
smartCSR: true,
terminal: "xterm-256color",
fullUnicode: true
});
let list = blessed.list({
parent: screen,
selectedBg: "blue",
mouse: true,
keys: true,
width: "50%"
});
list.setItems(ast.getLines());
list.select(0);
list.on("select item", (_, index) => {
let [start, end] = ast.getItemAtIndex(index).range;
codeBox.setContent(markCode(code, start, end));
screen.render();
});
let codeBox = blessed.box({
parent: screen,
width: "50%",
left: "50%",
border: {
type: "line",
fg: "#ffffff"
},
content: code
});
screen.key("q", function(ch, key) {
return process.exit(0);
});
screen.render();

@ -0,0 +1,18 @@
'use strict';
const chalk = require("chalk");
const ansiStyles = require("ansi-styles");
module.exports = function colorizedNodeType(astNode) {
let nodeType = astNode.type;
if (nodeType === "FunctionDeclaration" || nodeType === "ArrowFunctionExpression") {
return chalk.cyan(nodeType);
} else if (nodeType === "CallExpression") {
return chalk.green(nodeType);
} else if (nodeType === "ReturnStatement") {
return chalk.red(nodeType);
} else {
return ansiStyles.color.ansi256.rgb(100, 100, 100) + nodeType;
}
}

@ -0,0 +1,11 @@
'use strict';
const chalk = require("chalk");
module.exports = function markCode(code, startPosition, endPosition) {
return [
code.slice(0, startPosition),
chalk.bgBlue(code.slice(startPosition, endPosition)),
code.slice(endPosition)
].join("");
}

@ -0,0 +1,21 @@
'use strict';
const chalk = require("chalk");
const ansiStyles = require("ansi-styles");
const pad = require("pad");
function grayBackground(string) {
return ansiStyles.bgColor.ansi256.rgb(33, 33, 33) + string + ansiStyles.bgColor.close;
}
module.exports = function sectionTag(sectionName, {isArray} = {isArray: false}) {
let arrayPrefix;
if (isArray) {
arrayPrefix = chalk.red.bold("[]");
} else {
arrayPrefix = " ";
}
return `${arrayPrefix} ${grayBackground(`${pad(10, sectionName)} ->`)}`;
}

@ -0,0 +1,27 @@
'use strict';
function shortDescription(astNode) {
if (astNode.type === "FunctionDeclaration") {
return `function ${shortDescription(astNode.id)}(${renderArguments(astNode.params)}) { ... }`;
} else if (astNode.type === "ReturnStatement") {
return `return ${shortDescription(astNode.argument)}`;
} else if (astNode.type === "CallExpression") {
return `${shortDescription(astNode.callee)}(${renderArguments(astNode.arguments)})`;
} else if (astNode.type === "MemberExpression") {
return `${shortDescription(astNode.object)}.${shortDescription(astNode.property)}`;
} else if (astNode.type === "Identifier") {
return `${astNode.name}`;
} else if (astNode.type === "ArrowFunctionExpression") {
return `(${renderArguments(astNode.params)}) => { ... }`;
} else if (astNode.type === "Literal") {
return astNode.raw;
} else {
return "";
}
}
function renderArguments(args) {
return args.map(arg => shortDescription(arg)).join(", ");
}
module.exports = shortDescription;

@ -0,0 +1,87 @@
'use strict';
const archy = require("archy");
const chalk = require("chalk");
const memoizee = require("memoizee");
const assureArray = require("assure-array");
const util = require("util");
const colorizedNodeType = require("./render/colorize-type");
const shortDescription = require("./render/short-description");
const sectionTag = require("./render/section-tag");
module.exports = function visualizeAST(ast) {
let indexedItems = []; // NOTE: Impure, but is necessary to make getItemAtIndex work...
function sectionLabel(name, items) {
return {
label: chalk.yellow(`${name}:`),
nodes: items
}
}
function convertChildNodes(key, childNodes) {
let arrayifiedNodes = assureArray(childNodes);
let treeNodes = arrayifiedNodes.map((node) => {
let treeNode = astNodeToTreeNode(node);
treeNode.label = sectionTag(key, {isArray: Array.isArray(childNodes)}) + " " + treeNode.label;
return treeNode;
});
return treeNodes;
}
function astNodeToTreeNode(astNode) {
indexedItems.push(astNode);
let nodeLabel = `${chalk.bold(colorizedNodeType(astNode))} ${shortDescription(astNode)}`;
let primitiveProperties = [], singleChildren = [], multipleChildren = [];
Object.keys(astNode).forEach((key) => {
if (key === "loc" || key === "range") {
/* These are Esprima annotations. */
return;
}
let value = astNode[key];
if (typeof value === "string" || typeof value === "boolean" || typeof value === "number" || value == null) {
primitiveProperties.push(key);
} else if (Array.isArray(value)) {
if (value.length > 0) {
multipleChildren.push(key);
}
} else if (typeof value === "object" && value.type != null) {
singleChildren.push(key);
} else {
throw new Error(`Encountered unrecognized value type in AST: ${typeof value} -- ${util.inspect(value)}`);
}
});
let childNodes = (singleChildren.concat(multipleChildren)).map((key) => {
return convertChildNodes(key, astNode[key]);
}).reduce((combined, array) => {
return combined.concat(array);
}, []);
return {
label: nodeLabel,
nodes: childNodes
}
}
return {
getString: memoizee(function getString() {
let treeNodes = astNodeToTreeNode(ast);
return archy(treeNodes);
}),
getLines: function getLines() {
return this.getString().split("\n");
},
getItemAtIndex: function getItemAtIndex(index) {
return indexedItems[index];
}
}
}

@ -0,0 +1,26 @@
{
"name": "vulnerability-scanner",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.cryto.net:joepie91/vulnerability-scanner.git"
},
"keywords": [],
"author": "Sven Slootweg",
"license": "WTFPL",
"dependencies": {
"ansi-styles": "^3.0.0",
"archy": "^1.0.0",
"assure-array": "^1.0.0",
"blessed": "^0.1.81",
"chalk": "^1.1.3",
"esprima": "^3.1.3",
"memoizee": "^0.4.1",
"pad": "^1.0.2"
}
}

@ -0,0 +1,14 @@
'use strict';
function getContentWithComments() {
return Promise.try(() => {
return knex('content');
}).map((row) => {
return Promise.try(() => {
return knex('comments').where('content', row.id);
}).then((comments) => {
row.comments = comments;
return row;
});
});
}
Loading…
Cancel
Save