<commit_before>#!/usr/bin/env node
/**
 *	Copyright (c) 2015-2017 Vör Security Inc.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	    * Redistributions of source code must retain the above copyright
 *	      notice, this list of conditions and the following disclaimer.
 *	    * Redistributions in binary form must reproduce the above copyright
 *	      notice, this list of conditions and the following disclaimer in the
 *	      documentation and/or other materials provided with the distribution.
 *	    * Neither the name of the <organization> nor the
 *	      names of its contributors may be used to endorse or promote products
 *	      derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** Read through the package.json file in a specified directory. Build
 * a map of best case dependencies and indicate if there are any known
 * vulnerabilities.
 */

//sumarize results in JUnit with this
var DOMParser = require('xmldom').DOMParser;
var XMLSerializer = require('xmldom').XMLSerializer;
//write found vulnerabilities to JUnit xml
var jsontoxml = require('jsontoxml');

// File system access
var fs = require('fs');

// Next two requires used to get version from out package.json file
var path = require('path');
var pkg = require( path.join(__dirname, 'package.json') );

// Actual auditing "library". The library uses the OSS Index REST API
// to retrieve dependency information.
var auditor = require('./audit-package');

// Adds colors to console output
var colors = require('colors/safe');

// Decode HTML entities
var Entities = require('html-entities').AllHtmlEntities;
var entities = new Entities();

// Semantic version code
var semver = require('semver');

// dictionary of vulnerable packages for xml-report
var JUnit = { 'testsuite':[] };

// Used to find installed packages and their dependencies
var npm = require('npm');

/**
 * Total number of dependencies being audited. This will be set
 * before starting the audit.
 */
var expectedAudits = 0;

/**
 * Total number of dependencies audited so far.
 */
var actualAudits = 0;

/**
 * List of dependencies that we want to check after the package checks.
 */
var dependencies = [];

/**
 * Count encountered vulnerabilities
 */
var vulnerabilityCount = 0;

//Parse command line options. We currently support only one argument so
// this is a little overkill. It allows for future growth.
var program = require('commander');
program
.version(pkg.version)
.option('-p --package [package.json]', 'Specific package.json file to audit')
.option('-v --verbose', 'Print all vulnerabilities')
.option('-n --noNode', 'Ignore node executable')
.option('-o --output [output.xml]', 'Output file for xml-report.')
.action(function () {
});

program.on('--help', function(){
	usage();
});

program.parse(process.argv);

var output = program['output'] ? program['output'] : `${program[ 'package' ].toString().split( '.json' ).slice(0, -1)}_vulnerabilities.json`;

// By default we run an audit against all installed packages and their
// dependencies.
if (!program["package"]) {
	npm.load(function(err, npm) {
	    npm.commands.ls([], true, function(err, data, lite) {
			// Get a flat list of dependencies instead of a map.
			var deps = getDependencyList(data.dependencies);
			
			if(program.noNode) {
				// Set the number of expected audits
				expectedAudits = deps.length;
				
				// Only check dependencies
				auditor.auditPackages(deps, resultCallback);
			}
			else {
				// Set the number of expected audits
				expectedAudits = deps.length + 1; // +1 for hardcoded nodejs test
				
				// First check for node itself. We use the 'chocolatey' package manager
				// to hang this query on.
				auditor.auditPackage("chocolatey", "nodejs", process.version, function(err, data) {
					resultCallback(err, data);
					
					// Now check for the dependencies
					auditor.auditPackages(deps, resultCallback);
				});
			}
	    });
	});
}

// If a package.json file is specified, do an audit on the dependencies
// in the file only.
else {
	//Load the target package file
	var filename = program["package"];
	var targetPkg = undefined;
	
	try {
		// default encoding is utf8
		encoding = 'utf8';
	
		// read file synchroneously
		var contents = fs.readFileSync(filename, encoding);
	
		// parse contents as JSON
		targetPkg = JSON.parse(contents);
	
	} catch (err) {
		// an error occurred
		throw err;	
	}
	
	// Call the auditor library passing the dependency list from the
	// package.json file. The second argument is a callback that will
	// print the results to the console.
	if(targetPkg.dependencies != undefined) {
		// Get a flat list of dependencies instead of a map.
		var deps = getDependencyList(targetPkg.dependencies);
		expectedAudits = deps.length;
		auditor.auditPackages(deps, resultCallback);
	}
}

/** Set the return value
 * 
 * @param options
 * @param err
 * @returns
 */
function exitHandler(options, err) {
   JUnit = jsontoxml(JUnit);
   console.log(JUnit);
   var dom = new DOMParser().parseFromString(JUnit);
   dom.documentElement.setAttribute('name', 'audit_security');
   dom.documentElement.setAttribute('errors', 0);
   dom.documentElement.setAttribute('tests', expectedAudits);
   dom.documentElement.setAttribute('failures', vulnerabilityCount);
   dom.documentElement.setAttribute('package', 'audit_security');
   dom.documentElement.setAttribute('id', '');
   JUnit = new XMLSerializer().serializeToString(dom);
   fs.writeFileSync( output, `<?xml version="1.0" encoding="UTF-8"?>\n${JUnit}`);
   process.exit(vulnerabilityCount);
}

//do something when app is closing
process.on('exit', exitHandler.bind(null,{cleanup:true}));

//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit:true}));

//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));

/** Recursively get a flat list of dependency objects. This is simpler for
 * subsequent code to handle then a tree of dependencies.
 * 
 * @param depMap
 * @returns A list of dependency objects
 */
function getDependencyList(depMap) {
	var results = [];
	var lookup = {};
	var keys = Object.keys(depMap);
	for(var i = 0; i < keys.length; i++) {
		var name = keys[i];
		
		// The value of o depends on the type of structure we are passed
		var o = depMap[name];<commit_msg>Play around with jenkins displaying JUnit results.<commit_after>#!/usr/bin/env node
/**
 *	Copyright (c) 2015-2017 Vör Security Inc.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	    * Redistributions of source code must retain the above copyright
 *	      notice, this list of conditions and the following disclaimer.
 *	    * Redistributions in binary form must reproduce the above copyright
 *	      notice, this list of conditions and the following disclaimer in the
 *	      documentation and/or other materials provided with the distribution.
 *	    * Neither the name of the <organization> nor the
 *	      names of its contributors may be used to endorse or promote products
 *	      derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** Read through the package.json file in a specified directory. Build
 * a map of best case dependencies and indicate if there are any known
 * vulnerabilities.
 */

//sumarize results in JUnit with this
var DOMParser = require('xmldom').DOMParser;
var XMLSerializer = require('xmldom').XMLSerializer;
//write found vulnerabilities to JUnit xml
var jsontoxml = require('jsontoxml');

// File system access
var fs = require('fs');

// Next two requires used to get version from out package.json file
var path = require('path');
var pkg = require( path.join(__dirname, 'package.json') );

// Actual auditing "library". The library uses the OSS Index REST API
// to retrieve dependency information.
var auditor = require('./audit-package');

// Adds colors to console output
var colors = require('colors/safe');

// Decode HTML entities
var Entities = require('html-entities').AllHtmlEntities;
var entities = new Entities();

// Semantic version code
var semver = require('semver');

// dictionary of vulnerable packages for xml-report
var JUnit = { 'testsuite':[] };

// Used to find installed packages and their dependencies
var npm = require('npm');

/**
 * Total number of dependencies being audited. This will be set
 * before starting the audit.
 */
var expectedAudits = 0;

/**
 * Total number of dependencies audited so far.
 */
var actualAudits = 0;

/**
 * List of dependencies that we want to check after the package checks.
 */
var dependencies = [];

/**
 * Count encountered vulnerabilities
 */
var vulnerabilityCount = 0;

//Parse command line options. We currently support only one argument so
// this is a little overkill. It allows for future growth.
var program = require('commander');
program
.version(pkg.version)
.option('-p --package [package.json]', 'Specific package.json file to audit')
.option('-v --verbose', 'Print all vulnerabilities')
.option('-n --noNode', 'Ignore node executable')
.option('-o --output [output.xml]', 'Output file for xml-report.')
.action(function () {
});

program.on('--help', function(){
	usage();
});

program.parse(process.argv);

var output = program['output'] ? program['output'] : `${program[ 'package' ].toString().split( '.json' ).slice(0, -1)}_vulnerabilities.json`;

// By default we run an audit against all installed packages and their
// dependencies.
if (!program["package"]) {
	npm.load(function(err, npm) {
	    npm.commands.ls([], true, function(err, data, lite) {
			// Get a flat list of dependencies instead of a map.
			var deps = getDependencyList(data.dependencies);
			
			if(program.noNode) {
				// Set the number of expected audits
				expectedAudits = deps.length;
				
				// Only check dependencies
				auditor.auditPackages(deps, resultCallback);
			}
			else {
				// Set the number of expected audits
				expectedAudits = deps.length + 1; // +1 for hardcoded nodejs test
				
				// First check for node itself. We use the 'chocolatey' package manager
				// to hang this query on.
				auditor.auditPackage("chocolatey", "nodejs", process.version, function(err, data) {
					resultCallback(err, data);
					
					// Now check for the dependencies
					auditor.auditPackages(deps, resultCallback);
				});
			}
	    });
	});
}

// If a package.json file is specified, do an audit on the dependencies
// in the file only.
else {
	//Load the target package file
	var filename = program["package"];
	var targetPkg = undefined;
	
	try {
		// default encoding is utf8
		encoding = 'utf8';
	
		// read file synchroneously
		var contents = fs.readFileSync(filename, encoding);
	
		// parse contents as JSON
		targetPkg = JSON.parse(contents);
	
	} catch (err) {
		// an error occurred
		throw err;	
	}
	
	// Call the auditor library passing the dependency list from the
	// package.json file. The second argument is a callback that will
	// print the results to the console.
	if(targetPkg.dependencies != undefined) {
		// Get a flat list of dependencies instead of a map.
		var deps = getDependencyList(targetPkg.dependencies);
		expectedAudits = deps.length;
		auditor.auditPackages(deps, resultCallback);
	}
}

/** Set the return value
 * 
 * @param options
 * @param err
 * @returns
 */
function exitHandler(options, err) {
   JUnit = jsontoxml(JUnit);
   console.log(JUnit);
   var dom = new DOMParser().parseFromString(JUnit);
   dom.documentElement.setAttribute('name', 'audit_security');
   dom.documentElement.setAttribute('errors', 0);
   dom.documentElement.setAttribute('tests', expectedAudits);
   dom.documentElement.setAttribute('failures', vulnerabilityCount);
   dom.documentElement.setAttribute('package', 'test');
   dom.documentElement.setAttribute('id', '');
   dom.documentElement.setAttribute('skipped', expectedAudits-actualAudits);
   JUnit = new XMLSerializer().serializeToString(dom);
   fs.writeFileSync( output, `<?xml version="1.0" encoding="UTF-8"?>\n${JUnit}`);
   process.exit(vulnerabilityCount);
}

//do something when app is closing
process.on('exit', exitHandler.bind(null,{cleanup:true}));

//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit:true}));

//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));

/** Recursively get a flat list of dependency objects. This is simpler for
 * subsequent code to handle then a tree of dependencies.
 * 
 * @param depMap
 * @returns A list of dependency objects
 */
function getDependencyList(depMap) {
	var results = [];
	var lookup = {};
	var keys = Object.keys(depMap);
	for(var i = 0; i < keys.length; i++) {
		var name = keys[i];
		
		// The value of o depends on the type of structure we are passed
		var o = depMap[name];
{'fraction_non_alphanumeric': 0.11030119653417687, 'fraction_numerical': 0.0030257186081694403, 'mean_word_length': 3.8671352074966534, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 2, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2570284', 'n_tokens_mistral': 4380, 'n_tokens_neox': 4027, 'n_words': 1569}