Initial commit
commit
2f1d820509
@ -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…
Reference in New Issue