3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/.buildpath
|
||||
/.project
|
||||
/.settings/
|
@ -1,3 +1,5 @@
|
||||
## v1.3.3
|
||||
|
||||
## v1.3.2
|
||||
- Initial GitHub load
|
||||
- Previous versions loaded on [SourceForge](https://sourceforge.net/projects/sagacity/)
|
6
Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM php:7.2.8-apache-stretch
|
||||
COPY conf/docker-php.ini /usr/local/etc/php/php.ini
|
||||
RUN apt update && apt -y install zlib1g-dev mysql-client
|
||||
RUN docker-php-ext-install mysqli zip
|
||||
RUN mkdir /var/log/sagacity && chown www-data:www-data /var/log/sagacity
|
||||
EXPOSE 80
|
16
ajax.php
@ -52,7 +52,7 @@ include_once 'config.inc';
|
||||
include_once 'import.inc';
|
||||
include_once 'helper.inc';
|
||||
|
||||
chdir(DOC_ROOT);
|
||||
chdir(dirname(__FILE__));
|
||||
|
||||
$db = new db();
|
||||
$conn = new mysqli(DB_SERVER, "web", db::decrypt_pwd(), 'sagacity');
|
||||
@ -202,8 +202,10 @@ elseif ($action == 'delete-cat') {
|
||||
}
|
||||
}
|
||||
elseif ($action == 'delete-file') {
|
||||
$file = TMP . "/" . filter_input(INPUT_POST, 'filename', FILTER_SANITIZE_STRING);
|
||||
if (file_exists($file)) {
|
||||
$file = filter_input(INPUT_POST, 'filename', FILTER_SANITIZE_STRING);
|
||||
$file = realpath($file);
|
||||
|
||||
if ($file && preg_match("/^" . preg_quote(TMP, '/') . "/", $file)) {
|
||||
if (unlink($file)) {
|
||||
print header(JSON) . json_encode([
|
||||
'success' => 'Deleted file'
|
||||
@ -216,6 +218,7 @@ elseif ($action == 'delete-file') {
|
||||
}
|
||||
}
|
||||
else {
|
||||
$file = filter_input(INPUT_POST, 'filename', FILTER_SANITIZE_STRING);
|
||||
print header(JSON) . json_encode([
|
||||
'error' => "$file does not exist"
|
||||
]);
|
||||
@ -1470,7 +1473,7 @@ function update_stig_control()
|
||||
*
|
||||
* @param int $cat_id
|
||||
*
|
||||
* @return type
|
||||
* @return mixed
|
||||
*/
|
||||
function get_hosts($cat_id = null)
|
||||
{
|
||||
@ -1490,7 +1493,7 @@ function get_hosts($cat_id = null)
|
||||
return json_encode(['error' => "Invalid info"]);
|
||||
}
|
||||
|
||||
foreach ($tgts as $key => $tgt) {
|
||||
foreach ($tgts as $tgt) {
|
||||
$chks = $db->get_Target_Checklists($tgt->get_ID());
|
||||
if ($cat_id) {
|
||||
$exp_scan_srcs = $db->get_Expected_Category_Sources($ste_cat);
|
||||
@ -1502,6 +1505,7 @@ function get_hosts($cat_id = null)
|
||||
$icons = [];
|
||||
$icon_str = '';
|
||||
$src_str = '';
|
||||
sort($chks);
|
||||
|
||||
foreach ($chks as $chk) {
|
||||
if (!in_array($chk->get_Icon(), array_keys($icons))) {
|
||||
@ -1515,7 +1519,7 @@ function get_hosts($cat_id = null)
|
||||
$icon_str .= "<img src='/img/checklist_icons/$icon' title='{$data['name']}' class='checklist_image' />";
|
||||
}
|
||||
|
||||
foreach ($scan_srcs as $key => $src) {
|
||||
foreach ($scan_srcs as $src) {
|
||||
$icon = $src['src']->get_Icon();
|
||||
if($src['scan_error']) {
|
||||
$icon = strtolower($src['src']->get_Name()) . "-failed.png";
|
||||
|
@ -312,8 +312,11 @@ class checklist
|
||||
case (preg_match("/AIX/i", $this->name) ? true : false):
|
||||
$this->icon = 'AIX.png';
|
||||
break;
|
||||
case (preg_match("/Application Security|Application Server|Application Layer Gateway/i", $this->name) ? true : false):
|
||||
case (preg_match("/Application Security|Application Layer Gateway/i", $this->name) ? true : false):
|
||||
$this->icon = 'Application Development.gif';
|
||||
break;
|
||||
case (preg_match("/Application Server/i", $this->name) ? true : false):
|
||||
$this->icon = 'Application Server.jpg';
|
||||
break;
|
||||
case (preg_match("/Active Directory/i", $this->name) ? true : false):
|
||||
$this->icon = 'Active Directory.png';
|
||||
@ -399,7 +402,7 @@ class checklist
|
||||
case (preg_match("/SharePoint/i", $this->name) ? true : false):
|
||||
$this->icon = 'Microsoft Sharepoint.png';
|
||||
break;
|
||||
case (preg_match("/Dot Net/i", $this->name) ? true : false):
|
||||
case (preg_match("/Dot Net|DotNet/i", $this->name) ? true : false):
|
||||
$this->icon = 'Microsoft .NET.png';
|
||||
break;
|
||||
case (preg_match("/Internet Explorer/i", $this->name) ? true : false):
|
||||
@ -574,6 +577,33 @@ class checklist
|
||||
break;
|
||||
case (preg_match("/Mainframe /i", $this->name) ? true : false):
|
||||
$this->icon = 'mainframe.png';
|
||||
break;
|
||||
case (preg_match("/HBSS/i", $this->name) ? true : false):
|
||||
$this->icon = 'HBSS.jpg';
|
||||
break;
|
||||
case (preg_match("/Akamai/i", $this->name) ? true : false):
|
||||
$this->icon = 'Akamai.png';
|
||||
break;
|
||||
case (preg_match("/ArcGIS/i", $this->name) ? true : false):
|
||||
$this->icon = 'ArcGIS.png';
|
||||
break;
|
||||
case (preg_match("/Bromium/i", $this->name) ? true : false):
|
||||
$this->icon = 'Bromium.png';
|
||||
break;
|
||||
case (preg_match("/Forescout/i", $this->name) ? true : false):
|
||||
$this->icon = 'Forescout.jpg';
|
||||
break;
|
||||
case (preg_match("/DB Networks|DBN\-6300/i", $this->name) ? true : false):
|
||||
$this->icon = 'DB Networks.png';
|
||||
break;
|
||||
case (preg_match("/Windows PAW/i", $this->name) ? true : false):
|
||||
$this->icon = 'Windows PAW.jpg';
|
||||
break;
|
||||
case (preg_match("/SecNet/i", $this->name) ? true : false):
|
||||
$this->icon = 'Harris SecNet.jpg';
|
||||
break;
|
||||
case (preg_match("/Desktop App/i", $this->name) ? true : false):
|
||||
$this->icon = 'Desktop Application.jpg';
|
||||
break;
|
||||
default:
|
||||
$this->icon = 'Orphan.png';
|
||||
|
@ -104,7 +104,7 @@ class scan
|
||||
/**
|
||||
* Enum defining the type of script
|
||||
*
|
||||
* @var file_types
|
||||
* @var string
|
||||
*/
|
||||
protected $type = null;
|
||||
|
||||
@ -419,7 +419,7 @@ class scan
|
||||
/**
|
||||
* Getter function for the scan type
|
||||
*
|
||||
* @return file_types
|
||||
* @return string
|
||||
*/
|
||||
public function get_Type()
|
||||
{
|
||||
@ -429,7 +429,7 @@ class scan
|
||||
/**
|
||||
* Setter function for the scan type
|
||||
*
|
||||
* @param file_types $type_in
|
||||
* @param string $type_in
|
||||
*/
|
||||
public function set_Type($type_in)
|
||||
{
|
||||
@ -512,6 +512,30 @@ class scan
|
||||
$this->status = $status_in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if the scan has been terminated by the user
|
||||
*/
|
||||
public function isTerminated()
|
||||
{
|
||||
global $db, $log;
|
||||
$db->help->select("scans", ['status'], [
|
||||
[
|
||||
'field' => 'id',
|
||||
'op' => '=',
|
||||
'value' => $this->id
|
||||
]
|
||||
]);
|
||||
$thread_status = $db->help->execute();
|
||||
|
||||
$this->status = $thread_status['status'];
|
||||
|
||||
if ($this->status == TERMINIATED) {
|
||||
rename(realpath(TMP . "/{$this->file_name}"), TMP . "/terminated/{$this->file_name}");
|
||||
$log->notice("File parsing terminated by user");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function for the percentage the script has completed
|
||||
*
|
||||
|
14
conf/docker-php.ini
Normal file
@ -0,0 +1,14 @@
|
||||
memory_limit=1024M
|
||||
error_reporting=E_ALL
|
||||
display_errors=On
|
||||
display_startup_errors=On
|
||||
html_errors=On
|
||||
variables_order="GPCS"
|
||||
request_order="GPCS"
|
||||
post_max_size=1G
|
||||
include_path="./:/var/www/html:/var/www/html/classes:/var/www/html/inc"
|
||||
file_uploads=On
|
||||
upload_max_filesize=1G
|
||||
allow_url_fopen=On
|
||||
allow_url_include=Off
|
||||
date.timezone=America/Indiana/Indianapolis
|
@ -15,6 +15,7 @@
|
||||
* - Nov 14, 2017 - File created
|
||||
* - May 24, 2018 - Updated constants for 1.3.2 release
|
||||
* - Jun 2, 2018 - Added new STIG_EXCLUSIONS constant to permanently exclude STIGs
|
||||
* - Aug 28, 2018 - Updated constants for 1.3.3 release
|
||||
*/
|
||||
// @new
|
||||
/**
|
||||
@ -29,8 +30,8 @@ define('E_DEBUG', 65535);
|
||||
define('DOC_ROOT', '{DOC_ROOT}');
|
||||
define('PWD_FILE', '{PWD_FILE}');
|
||||
define('TMP', '{TMP_PATH}');
|
||||
define('VER', '1.3.2');
|
||||
define('REL_DATE', '2018-05-31');
|
||||
define('VER', '1.3.3');
|
||||
define('REL_DATE', '2018-08-31');
|
||||
define('LOG_LEVEL', '{E_ERROR}');
|
||||
define('LOG_PATH', '{LOG_PATH}');
|
||||
define('SALT', '{SALT}');
|
||||
@ -59,6 +60,7 @@ define('NOTIFICATIONS', '{NOTIFICATIONS}');
|
||||
define('PORT_LIMIT', '{PORT_LIMIT}');
|
||||
define('MAX_RESULTS', '{MAX_RESULTS}');
|
||||
define('ECHECKLIST_FORMAT', '{ECHECKLIST_FORMAT}');
|
||||
define('UPDATE_FREQ', '{UPDATE_FREQ}');
|
||||
|
||||
/**
|
||||
* Company variables
|
||||
|
@ -80,8 +80,6 @@ $dbh = new db();
|
||||
|
||||
$files = glob("*.*");
|
||||
$stack = [];
|
||||
$running = [];
|
||||
$time = 0;
|
||||
$threads = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
|
@ -83,7 +83,6 @@ if (isset($cmd['d']) && $cmd['d']) {
|
||||
chdir($path);
|
||||
|
||||
$db = new db();
|
||||
$stack = [];
|
||||
$zip_files = glob("*.zip");
|
||||
$zip = new ZipArchive();
|
||||
|
||||
@ -155,7 +154,7 @@ foreach ($xml_files as $key => $file) {
|
||||
continue;
|
||||
}
|
||||
elseif(!empty(STIG_EXCLUSIONS) && preg_match("/" . STIG_EXCLUSIONS . "/i", $file)) {
|
||||
unlink($file);
|
||||
unlink(TMP . "/stigs/xml/$file");
|
||||
$log->debug("Skipping $file due to matching STIG exclusion");
|
||||
continue;
|
||||
}
|
||||
@ -235,7 +234,7 @@ if (isset($cmd['delete'])) {
|
||||
*/
|
||||
function directory_crawl($files)
|
||||
{
|
||||
global $zip;
|
||||
global $zip, $log;
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/\.zip/', $file)) {
|
||||
|
@ -40,7 +40,8 @@ $db_step = [
|
||||
'sample-data' => ['filter' => FILTER_VALIDATE_BOOLEAN],
|
||||
'cpe' => ['filter' => FILTER_VALIDATE_BOOLEAN],
|
||||
'cve' => ['filter' => FILTER_VALIDATE_BOOLEAN],
|
||||
'stig' => ['filter' => FILTER_VALIDATE_BOOLEAN]
|
||||
'stig' => ['filter' => FILTER_VALIDATE_BOOLEAN],
|
||||
'update-freq' => ['filter' => FILTER_VALIDATE_INT, 'flag' => FILTER_NULL_ON_FAILURE]
|
||||
];
|
||||
$company_step = [
|
||||
'company' => $params,
|
||||
@ -101,16 +102,26 @@ function save_Database($params)
|
||||
$php = null;
|
||||
$mysql = null;
|
||||
if (strtolower(substr(PHP_OS, 0, 3)) == 'lin') {
|
||||
$res = [];
|
||||
exec("which php", $res);
|
||||
if (file_exists('/bin/php')) {
|
||||
$php = realpath("/bin/php");
|
||||
}
|
||||
elseif (is_array($res) && isset($res[0]) && file_exists($res[0])) {
|
||||
$php = realpath($res[0]);
|
||||
}
|
||||
else {
|
||||
die(json_encode(['error' => 'Cannot find the PHP executable']));
|
||||
}
|
||||
|
||||
$res = [];
|
||||
exec("which mysql", $res);
|
||||
if (file_exists('/bin/mysql')) {
|
||||
$mysql = realpath('/bin/mysql');
|
||||
}
|
||||
elseif (is_array($res) && isset($res[0]) && file_exists($res[0])) {
|
||||
$mysql = realpath($res[0]);
|
||||
}
|
||||
else {
|
||||
die(json_encode(['error' => 'Cannot find the MySQL executable']));
|
||||
}
|
||||
@ -138,6 +149,7 @@ function save_Database($params)
|
||||
my_str_replace("{PHP_CONF}", realpath(php_ini_loaded_file()), $config);
|
||||
my_str_replace("{DB_SERVER}", $params['db-server'], $config);
|
||||
my_str_replace("{DB_BIN}", $mysql, $config);
|
||||
my_str_replace("'{UPDATE_FREQ}'", $params['update-freq'], $config);
|
||||
my_str_replace("@new", "@step1", $config);
|
||||
|
||||
if (!file_exists($params['tmp-path'])) {
|
||||
|
@ -126,19 +126,7 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$db->help->select("scans", ['status'], [
|
||||
[
|
||||
'field' => 'id',
|
||||
'op' => '=',
|
||||
'value' => $scan->get_ID()
|
||||
]
|
||||
]);
|
||||
$thread_status = $db->help->execute();
|
||||
if ($thread_status['status'] == 'TERMINATED') {
|
||||
unset($objSS);
|
||||
rename(realpath(TMP . "/{$scan->get_File_Name()}"), TMP . "/terminated/{$scan->get_File_Name()}");
|
||||
$log->notice("File parsing terminated by user");
|
||||
}
|
||||
$scan->isTerminated();
|
||||
|
||||
$log->notice("Reading from {$wksht->getTitle()}");
|
||||
|
||||
@ -163,35 +151,26 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
'notes' => 9,
|
||||
'check_contents' => 10
|
||||
];
|
||||
$finding_count = [];
|
||||
$tgts = [];
|
||||
$short_title_col = Coordinate::stringFromColumnIndex($idx['short_title']);
|
||||
$row_count = $wksht->getHighestDataRow() - 10;
|
||||
$row_count = $highestRow = $wksht->getHighestDataRow() - 10;
|
||||
$highestCol = $wksht->getHighestDataColumn(10);
|
||||
|
||||
foreach ($wksht->getRowIterator(10) as $row) {
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
for ($col = 'F' ; $col != $highestCol ; $col++) {
|
||||
$cell = $wksht->getCell($col . '10');
|
||||
$log->debug("Checking column: {$cell->getColumn()} {$cell->getCoordinate()}");
|
||||
$ip = null;
|
||||
$db->help->select("scans", ['status'], [
|
||||
[
|
||||
'field' => 'id',
|
||||
'op' => '=',
|
||||
'value' => $scan->get_ID()
|
||||
]
|
||||
]);
|
||||
$thread_status = $db->help->execute();
|
||||
if ($thread_status['status'] == 'TERMINATED') {
|
||||
unset($objSS);
|
||||
rename(realpath(TMP . "/{$scan->get_File_Name()}"), TMP . "/terminated/{$scan->get_File_Name()}");
|
||||
die($log->notice("File parsing terminated by user"));
|
||||
}
|
||||
|
||||
if ($cell->getColumn() > $short_title_col && !preg_match('/Overall/i', $cell->getValue())) {
|
||||
$scan->isTerminated();
|
||||
|
||||
if (!preg_match('/Overall/i', $cell->getValue())) {
|
||||
if (preg_match('/status/i', $cell->getValue())) {
|
||||
$log->error("Invalid host name ('status') in {$wksht->getTitle()}");
|
||||
break;
|
||||
}
|
||||
|
||||
if ($tgt_id = $db->check_Target($conf['ste'], $cell->getValue())) {
|
||||
$log->debug("Found host for {$cell->getValue()}");
|
||||
$tgt = $db->get_Target_Details($conf['ste'], $tgt_id);
|
||||
if (is_array($tgt) && count($tgt) && isset($tgt[0]) && is_a($tgt[0], 'target')) {
|
||||
$tgt = $tgt[0];
|
||||
@ -201,6 +180,7 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
$log->debug("Creating new target {$cell->getValue()}");
|
||||
$tgt = new target($cell->getValue());
|
||||
$tgt->set_OS_ID($gen_os->get_ID());
|
||||
$tgt->set_STE_ID($conf['ste']);
|
||||
@ -218,6 +198,7 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
|
||||
$tgts[] = $tgt;
|
||||
|
||||
$log->debug("Adding new target to host list", ['row_count' => $row_count, 'tgt_id' => $tgt->get_ID(), 'tgt_name' => $tgt->get_Name()]);
|
||||
$hl = new host_list();
|
||||
$hl->setFindingCount($row_count);
|
||||
$hl->setTargetId($tgt->get_ID());
|
||||
@ -239,20 +220,20 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
}
|
||||
|
||||
if (preg_match('/Overall/i', $cell->getValue())) {
|
||||
$log->debug("Found overall: {$cell->getColumn()}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$db->update_Running_Scan($base_name, ['name' => 'host_count', 'value' => count($tgts)]);
|
||||
|
||||
// increment the column indexes for notes, check contents, and missing PDI
|
||||
if (is_array($tgts) && count($tgts) > 1) {
|
||||
$idx['overall'] += count($tgts);
|
||||
$idx['consistent'] += count($tgts);
|
||||
$idx['notes'] += count($tgts);
|
||||
$idx['check_contents'] += count($tgts);
|
||||
$increase = count($tgts) - 1;
|
||||
$idx['overall'] += $increase;
|
||||
$idx['consistent'] += $increase;
|
||||
$idx['notes'] += $increase;
|
||||
$idx['check_contents'] += $increase;
|
||||
}
|
||||
elseif (empty($tgts)) {
|
||||
$log->warning("Failed to identify targets in worksheet {$wksht->getTitle()}");
|
||||
@ -266,8 +247,21 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
$title_col = Coordinate::stringFromColumnIndex($idx['short_title']);
|
||||
$notes_col = Coordinate::stringFromColumnIndex($idx['notes']);
|
||||
|
||||
$log->debug("Columns", [
|
||||
'stig_col' => $stig_col,
|
||||
'vms_col' => $vms_col,
|
||||
'cat_col' => $cat_col,
|
||||
'ia_col' => $ia_col,
|
||||
'title_col' => $title_col,
|
||||
'overall_col' => Coordinate::stringFromColumnIndex($idx['overall']),
|
||||
'consistent_col' => Coordinate::stringFromColumnIndex($idx['consistent']),
|
||||
'check_contents_col' => Coordinate::stringFromColumnIndex($idx['check_contents']),
|
||||
'notes_col' => $notes_col
|
||||
]);
|
||||
|
||||
$new_findings = [];
|
||||
$updated_findings = [];
|
||||
$row_count = 0;
|
||||
|
||||
foreach ($wksht->getRowIterator(11) as $row) {
|
||||
$stig_id = $wksht->getCell("{$stig_col}{$row->getRowIndex()}")->getValue();
|
||||
@ -276,6 +270,9 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
$notes = $wksht->getCell("{$notes_col}{$row->getRowIndex()}")->getValue();
|
||||
|
||||
$stig = $db->get_Stig($stig_id);
|
||||
if($row->getRowIndex() % 10 == 0) {
|
||||
$scan->isTerminated();
|
||||
}
|
||||
|
||||
if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) {
|
||||
$stig = $stig[0];
|
||||
@ -302,6 +299,7 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
$finding = $db->get_Finding($tgt, $stig);
|
||||
|
||||
if (is_array($finding) && count($finding) && isset($finding[0]) && is_a($finding[0], 'finding')) {
|
||||
/** @var finding $tmp */
|
||||
$tmp = $finding[0];
|
||||
|
||||
if(preg_match("/Not a Finding|Not Applicable/i", $status)) {
|
||||
@ -327,11 +325,20 @@ foreach ($objSS->getWorksheetIterator() as $wksht) {
|
||||
$x++;
|
||||
}
|
||||
|
||||
if (PHP_SAPI == 'cli') {
|
||||
print "\r" . sprintf("%.2f%%", (($row->getRowIndex() - 10) / $row_count) * 100);
|
||||
$row_count++;
|
||||
|
||||
if($row_count % 100 == 0) {
|
||||
if(!$db->add_Findings_By_Target($updated_findings, $new_findings)) {
|
||||
die(print_r(debug_backtrace(), true));
|
||||
} else {
|
||||
$updated_findings = [];
|
||||
$new_findings = [];
|
||||
}
|
||||
else {
|
||||
$db->update_Running_Scan($base_name, ['name' => 'perc_comp', 'value' => (($row->getRowIndex() - 10) / $row_count) * 100]);
|
||||
}
|
||||
|
||||
$db->update_Running_Scan($base_name, ['name' => 'perc_comp', 'value' => (($row->getRowIndex() - 10) / $highestRow) * 100]);
|
||||
if (PHP_SAPI == 'cli') {
|
||||
print "\r" . sprintf("%.2f%%", (($row->getRowIndex() - 10) / $highestRow) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +582,8 @@ class nessus_parser extends scan_xml_parser
|
||||
$this->log->script_log("Skipping tcp6 ports because there are " . count($netstat_keys) . " listening", E_DEBUG);
|
||||
}
|
||||
|
||||
$this->tgt->set_ID($this->db->save_Target($this->tgt));
|
||||
$this->tgt->set_PP_Flag(true);
|
||||
$this->tgt->set_ID($this->db->save_Target($this->tgt, false));
|
||||
|
||||
$dt = DateTime::createFromFormat("D M d H:i:s Y", $this->tag["HOST_START"]);
|
||||
if ($dt < $this->scan->get_File_DateTime()) {
|
||||
@ -1332,7 +1333,8 @@ class nessus_parser extends scan_xml_parser
|
||||
{
|
||||
$this->log->script_log("ReportHost_end-START: {$this->tgt->get_Name()}");
|
||||
// save findings
|
||||
$this->db->save_Target($this->tgt);
|
||||
$this->tgt->set_PP_flag(true);
|
||||
$this->db->save_Target($this->tgt, false);
|
||||
|
||||
$this->log->script_log("Added finding counts: " . count($this->new_findings) . " for target " . $this->tgt->get_Name());
|
||||
$this->log->script_log("Updated finding counts: " . count($this->updated_findings) . " for target " . $this->tgt->get_Name());
|
||||
@ -1363,6 +1365,8 @@ class nessus_parser extends scan_xml_parser
|
||||
{
|
||||
$this->log->script_log("Saving host list");
|
||||
$this->db->update_Scan_Host_List($this->scan);
|
||||
|
||||
$this->db->post_Processing();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ foreach ($lines as $line_num => $line) {
|
||||
continue;
|
||||
} # skip blank lines
|
||||
$line = trim($line, "\t\n\r"); # chomp would be nice...
|
||||
$matches = [];
|
||||
if (!isset($filetype)) {
|
||||
if (preg_match('/Starting|\-oN/', $line)) {
|
||||
$filetype = "text";
|
||||
@ -242,8 +243,6 @@ if ($filetype == "xml") {
|
||||
$target[$ip]['description'] = $vendor;
|
||||
# Iterate through ports
|
||||
$ports = getValue($xml, "ports/port", $host, true);
|
||||
$tcp_ports = [];
|
||||
$udp_ports = [];
|
||||
foreach ($ports as $portxml) {
|
||||
$portid = $portxml->getAttribute("portid");
|
||||
$proto = $portxml->getAttribute("protocol");
|
||||
@ -284,6 +283,7 @@ if ($filetype == "xml") {
|
||||
$db->update_Running_Scan($base_name, ['name' => 'host_count', 'value' => count($target)]);
|
||||
$count = 0;
|
||||
$tgt_ip = null;
|
||||
|
||||
foreach ($target as $ip => $tgt) {
|
||||
# get target ID
|
||||
$tgt_id = 0;
|
||||
@ -302,6 +302,7 @@ foreach ($target as $ip => $tgt) {
|
||||
$tgt_obj->set_STE_ID($conf['ste']);
|
||||
//$tgt_obj->set_Notes("New target found by NMap");
|
||||
$tgt_obj->set_OS_ID($sw->get_ID());
|
||||
$tgt_obj->set_PP_Flag(true);
|
||||
if ($sw->get_Shortened_SW_String()) {
|
||||
$tgt_obj->set_OS_String($sw->get_Shortened_SW_String());
|
||||
}
|
||||
@ -344,10 +345,11 @@ foreach ($target as $ip => $tgt) {
|
||||
}
|
||||
}
|
||||
|
||||
$tgt_obj->set_ID($tgt_id = $db->save_Target($tgt_obj));
|
||||
$tgt_obj->set_ID($tgt_id = $db->save_Target($tgt_obj, false));
|
||||
}
|
||||
else { #Update
|
||||
$db_tgt = $db->get_Target_Details($conf['ste'], $tgt_id)[0];
|
||||
$db_tgt->set_PP_Flag(true);
|
||||
|
||||
if (isset($tgt['tcp'])) {
|
||||
foreach ($tgt['tcp'] as $port_num => $port) {
|
||||
@ -388,7 +390,7 @@ foreach ($target as $ip => $tgt) {
|
||||
}
|
||||
}
|
||||
|
||||
$db->save_Target($db_tgt);
|
||||
$db->save_Target($db_tgt, false);
|
||||
}
|
||||
|
||||
$count++;
|
||||
@ -406,6 +408,7 @@ foreach ($target as $ip => $tgt) {
|
||||
$db->update_Running_Scan($base_name, ['name' => 'last_host', 'value' => $db_tgt->get_Name()]);
|
||||
}
|
||||
|
||||
$db->post_Processing();
|
||||
$db->update_Scan_Host_List($scan);
|
||||
$db->update_Running_Scan($base_name, ['name' => 'perc_comp', 'value' => 100, 'complete' => 1]);
|
||||
if (!isset($cmd['debug'])) {
|
||||
|
@ -65,7 +65,6 @@ print "Currently " . count($existing_cves) . " in DB" . PHP_EOL . "Parsing: " .
|
||||
$db_cpes = [];
|
||||
$new_cves = [];
|
||||
$new_cve_refs = [];
|
||||
$new_cve_web = [];
|
||||
$sw_rows = [];
|
||||
$new = 0;
|
||||
$existing = 0;
|
||||
@ -82,9 +81,6 @@ $cve_fields = [
|
||||
$ref_fields = [
|
||||
'cve_seq', 'source', 'url', 'val'
|
||||
];
|
||||
$web_fields = [
|
||||
'cve_id', 'xml'
|
||||
];
|
||||
|
||||
foreach ($json->CVE_Items as $cve) {
|
||||
if (!isset($existing_cves["{$cve->cve->CVE_data_meta->ID}"])) {
|
||||
@ -168,18 +164,9 @@ foreach ($json->CVE_Items as $cve) {
|
||||
|
||||
$new_cves = [];
|
||||
$new_cve_refs = [];
|
||||
$new_cve_web = [];
|
||||
$sw_rows = [];
|
||||
|
||||
print "\t" . ($existing + $new) . " completed" . PHP_EOL;
|
||||
|
||||
$db->help->update("settings", ['meta_value' => number_format((($existing + $new) / count($json->CVE_Items)) * 100, 2)], [
|
||||
[
|
||||
'field' => 'meta_key',
|
||||
'value' => 'nvd-cve-progress'
|
||||
]
|
||||
]);
|
||||
$db->help->execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,8 @@
|
||||
* - Apr 29, 2018 - Added extract parameter to only extract nasl archive file, fixed a couple bugs
|
||||
* - May 10, 2018 - Removed ping of cve.mitre.org, and added 'po' and 'do' parameters for NVD CVE
|
||||
* - Jun 5, 2018 - Fixed a couple setting updates
|
||||
*/
|
||||
* - Sep 18, 2018 - Jeff - Added --sunset switch for Installing Sunset STIGs from https://iase.disa.mil/stigs/sunset/Pages/index.aspx
|
||||
*/
|
||||
include_once 'config.inc';
|
||||
include_once 'helper.inc';
|
||||
include_once 'error.inc';
|
||||
@ -61,11 +62,10 @@ use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
|
||||
$current_date = new DateTime();
|
||||
$total_time = null;
|
||||
$total_diff = 0;
|
||||
$summary_stats = [];
|
||||
$total_complete = 0;
|
||||
$threads = [];
|
||||
|
||||
$cmd = getopt("h::u::p::", ['cpe::', 'cce::', 'cve::', 'nvd::', 'nasl::', 'stig::', 'do::', 'po::', 'help::', 'debug::', 'extract::', 'exclude::']);
|
||||
$cmd = getopt("h::u::p::", ['cpe::', 'cce::', 'cve::', 'nvd::', 'nasl::', 'stig::', 'sunset::', 'do::', 'po::', 'help::', 'debug::', 'extract::', 'exclude::']);
|
||||
|
||||
$db = new db();
|
||||
$diff = new DateTimeDiff();
|
||||
@ -94,7 +94,7 @@ $log->pushHandler(new StreamHandler(LOG_PATH . "/update_db.log", $log_level));
|
||||
$log->pushHandler($stream);
|
||||
|
||||
if (isset($cmd['h'], $cmd['help']) ||
|
||||
(!isset($cmd['cpe']) && !isset($cmd['cve']) && !isset($cmd['nasl']) && !isset($cmd['stig']) && !isset($cmd['nvd']))) {
|
||||
(!isset($cmd['cpe']) && !isset($cmd['cve']) && !isset($cmd['nasl']) && !isset($cmd['stig']) && !isset($cmd['sunset']) && !isset($cmd['nvd']))) {
|
||||
die(usage());
|
||||
}
|
||||
|
||||
@ -361,9 +361,10 @@ if (isset($cmd['nvd'])) {
|
||||
$load_date = new DateTime($db->get_Settings("nvd-cve-load-date"));
|
||||
if ($load_date < $too_old) {
|
||||
// More than 7 days old so have to do a full load
|
||||
foreach ($nvd_years as $yr) {
|
||||
foreach ($nvd_years as $x => $yr) {
|
||||
$db->set_Setting('nvd-year', $yr);
|
||||
download_file("https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-{$yr}.json.zip", TMP . "/nvd/nvdcve-{$yr}.json.zip", $db->help, 'nvd-cve-dl-progress');
|
||||
$db->set_Setting('nvd-cve-dl-progress', (($x + 1) / count($nvd_years)) * 100);
|
||||
download_file("https://static.nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-{$yr}.json.zip", TMP . "/nvd/nvdcve-{$yr}.json.zip");
|
||||
$zip = new ZipArchive();
|
||||
$zip->open(TMP . "/nvd/nvdcve-{$yr}.json.zip");
|
||||
$zip->extractTo(TMP . "/nvd");
|
||||
@ -392,7 +393,7 @@ if (isset($cmd['nvd'])) {
|
||||
chdir(DOC_ROOT . "/exec");
|
||||
if (isset($cmd['po']) || !isset($cmd['do'])) {
|
||||
$json_files = glob(TMP . "/nvd/*.json");
|
||||
foreach ($json_files as $j) {
|
||||
foreach ($json_files as $x => $j) {
|
||||
$match = [];
|
||||
if (preg_match("/(\d{4}|recent|modified)/", basename($j), $match)) {
|
||||
$db->set_Setting('nvd-year', $match[1]);
|
||||
@ -407,6 +408,7 @@ if (isset($cmd['nvd'])) {
|
||||
|
||||
$log->debug("Running NVD CVE parsing script on file: $j");
|
||||
passthru($script);
|
||||
$db->set_Setting('nvd-cve-progress', (($x + 1) / count($json_files)) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,6 +460,7 @@ if (isset($cmd['nasl'])) {
|
||||
'nasl-progress' => 0,
|
||||
'nasl-count' => 0
|
||||
]);
|
||||
$count = 0;
|
||||
|
||||
// Capture start time for performance monitoring
|
||||
$diff->resetClock();
|
||||
@ -700,6 +703,75 @@ if (isset($cmd['stig'])) {
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Sunset STIG library from DISA content
|
||||
*/
|
||||
if (isset($cmd['sunset'])) {
|
||||
$db->set_Setting_Array([
|
||||
'stig-dl-progress' => 0,
|
||||
'stig-progress' => 0,
|
||||
'stig-count' => 0
|
||||
]);
|
||||
$path = TMP . "/stigs/zip";
|
||||
check_path($path);
|
||||
$sunset_array = [];
|
||||
|
||||
$diff->resetClock();
|
||||
print "Started Sunset STIG ingestion ({$diff->getStartClockTime()})" . PHP_EOL;
|
||||
|
||||
$sunset_url="https://iase.disa.mil/stigs/Lists/Sunset%20Master%20List/FinalView.aspx";
|
||||
|
||||
if (ping("disa.mil") && !isset($cmd['po'])) {
|
||||
$log->debug("Checking for $sunset_url");
|
||||
if ($found = url_exists($sunset_url)) {
|
||||
$contents=file_get_contents($sunset_url);
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$log->debug("Unable to download $sunset_url, aborting Sunset");
|
||||
die("Unable to open $sunset_url, aborting Sunset");
|
||||
}
|
||||
|
||||
preg_match_all("/a href=\"([^ ]+zip\/U_[^ ]+STIG\.zip)/", $contents, $sunset_array);
|
||||
|
||||
foreach($sunset_array[1] as $url) {
|
||||
$sunset_fname = basename($url);
|
||||
download_file($url, "{$path}/$sunset_fname");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($cmd['do']) || isset($cmd['po'])) {
|
||||
$stig_files = array_merge(
|
||||
glob("{$path}/*.zip"), glob("{$path}/*.xml"),
|
||||
glob(TMP . "/*.zip"), glob(TMP . "/*.xml"), glob(TMP . "/stigs/xml/*.xml")
|
||||
);
|
||||
if (!count($stig_files)) {
|
||||
die("Could not find any other zip files in " . realpath(TMP));
|
||||
}
|
||||
|
||||
$script = realpath(defined('PHP_BIN') ? PHP_BIN : PHP) .
|
||||
" -c " . realpath(PHP_CONF) .
|
||||
" -f " . realpath(DOC_ROOT . "/exec/background_stigs.php") . " --" .
|
||||
(isset($cmd['exclude']) && $cmd['exclude'] ? " --exclude=\"{$cmd['exclude']}\"" : "") .
|
||||
" --delete";
|
||||
|
||||
$log->debug("Script to run $script");
|
||||
passthru($script);
|
||||
}
|
||||
|
||||
$db->help->select_count("sagacity.stigs");
|
||||
$stig_count = $db->help->execute();
|
||||
|
||||
$db->set_Setting("stig-count", $stig_count);
|
||||
|
||||
$diff->stopClock();
|
||||
|
||||
print PHP_EOL . "Finished at {$diff->getEndClockTime()}" . PHP_EOL .
|
||||
"Total Time: {$diff->getDiffString()}" . PHP_EOL;
|
||||
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
if (is_a($diff->getTotalDiff(), 'DateInterval')) {
|
||||
print "Total Script Time: {$diff->getTotalDiffString()}" . PHP_EOL;
|
||||
}
|
||||
@ -721,6 +793,7 @@ Usage: php update_db.php [--cpe] [--cve] [--nvd] [--nasl] [--stig] [-u={URL}] [-
|
||||
--nasl To download OpenVAS NVT library and update NASL files
|
||||
You can also extract *.nasl files from the Nessus library to $tmp/nessus_plugins and it will include these in the update
|
||||
--stig To download and update the STIG library
|
||||
--sunset To download and update the STIG library with the STIGs DISA has archived
|
||||
|
||||
--do To download the files only...do not call the parsers will overwrite any existing files
|
||||
--po To parse the downloaded files only, do not download
|
||||
|
BIN
img/checklist_icons/Akamai.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
img/checklist_icons/Application Server.jpg
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
img/checklist_icons/ArcGIS.png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
img/checklist_icons/Bromium.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
img/checklist_icons/DB Networks.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
img/checklist_icons/Desktop Application.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
img/checklist_icons/Forescout.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
img/checklist_icons/Harris SecNet.jpg
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
img/checklist_icons/Windows PAW.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
@ -91,7 +91,7 @@
|
||||
},
|
||||
success: function (data) {
|
||||
if ($('#toggle_refresh').html() == 'Stop Refresh' && !to) {
|
||||
to = setTimeout(update_script_status, 3000);
|
||||
to = setTimeout(update_script_status, <?php print UPDATE_FREQ * 1000; ?>);
|
||||
}
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
|
1
inc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/passwd
|
@ -1,12 +1,31 @@
|
||||
{
|
||||
"require" : {
|
||||
"phpoffice/phpspreadsheet" : "^1.0",
|
||||
"cocur/background-process" : "^0.7.0",
|
||||
"tecnickcom/tcpdf" : "^6.2",
|
||||
"pacificsec/cpe" : "^1.0",
|
||||
"monolog/monolog": "^1.23"
|
||||
"phpoffice/phpspreadsheet" : "~1.4",
|
||||
"cocur/background-process" : "~0.7",
|
||||
"tecnickcom/tcpdf" : "~6.2",
|
||||
"pacificsec/cpe" : "1.0.1",
|
||||
"monolog/monolog" : "~1.23"
|
||||
},
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "^6.2"
|
||||
"phpunit/phpunit" : "~7.3"
|
||||
},
|
||||
"type" : "project",
|
||||
"homepage" : "https://cyberperspectives.com",
|
||||
"license" : "Apache-2.0",
|
||||
"authors" : [{
|
||||
"name" : "Ryan Prather",
|
||||
"email" : "ryan.prather@cyberperspectives.com",
|
||||
"role" : "Braun"
|
||||
}, {
|
||||
"name" : "Jeff Odegard",
|
||||
"email" : "jeff.odegard@cyberperspectives.com",
|
||||
"role" : "Brains"
|
||||
}
|
||||
],
|
||||
"keywords" : [
|
||||
"security",
|
||||
"disa",
|
||||
"rmf"
|
||||
],
|
||||
"name" : "cyberperspectives\\sagacity"
|
||||
}
|
418
inc/composer.lock
generated
@ -1,10 +1,10 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "92ac4709f5221f74a1c7f00e59df8ad7",
|
||||
"content-hash": "8bf5f4a76098ff9277648c58793a04b5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "cocur/background-process",
|
||||
@ -44,6 +44,101 @@
|
||||
],
|
||||
"time": "2017-02-11T12:41:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "1.4.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
|
||||
"reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0|^7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
|
||||
"phpcompatibility/php-compatibility": "^8.0",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "2.*",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.0",
|
||||
"sebastian/phpcpd": "2.*",
|
||||
"squizlabs/php_codesniffer": "^3.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
},
|
||||
"files": [
|
||||
"classes/src/functions/abs.php",
|
||||
"classes/src/functions/acos.php",
|
||||
"classes/src/functions/acosh.php",
|
||||
"classes/src/functions/acot.php",
|
||||
"classes/src/functions/acoth.php",
|
||||
"classes/src/functions/acsc.php",
|
||||
"classes/src/functions/acsch.php",
|
||||
"classes/src/functions/argument.php",
|
||||
"classes/src/functions/asec.php",
|
||||
"classes/src/functions/asech.php",
|
||||
"classes/src/functions/asin.php",
|
||||
"classes/src/functions/asinh.php",
|
||||
"classes/src/functions/atan.php",
|
||||
"classes/src/functions/atanh.php",
|
||||
"classes/src/functions/conjugate.php",
|
||||
"classes/src/functions/cos.php",
|
||||
"classes/src/functions/cosh.php",
|
||||
"classes/src/functions/cot.php",
|
||||
"classes/src/functions/coth.php",
|
||||
"classes/src/functions/csc.php",
|
||||
"classes/src/functions/csch.php",
|
||||
"classes/src/functions/exp.php",
|
||||
"classes/src/functions/inverse.php",
|
||||
"classes/src/functions/ln.php",
|
||||
"classes/src/functions/log2.php",
|
||||
"classes/src/functions/log10.php",
|
||||
"classes/src/functions/negative.php",
|
||||
"classes/src/functions/pow.php",
|
||||
"classes/src/functions/rho.php",
|
||||
"classes/src/functions/sec.php",
|
||||
"classes/src/functions/sech.php",
|
||||
"classes/src/functions/sin.php",
|
||||
"classes/src/functions/sinh.php",
|
||||
"classes/src/functions/sqrt.php",
|
||||
"classes/src/functions/tan.php",
|
||||
"classes/src/functions/tanh.php",
|
||||
"classes/src/functions/theta.php",
|
||||
"classes/src/operations/add.php",
|
||||
"classes/src/operations/subtract.php",
|
||||
"classes/src/operations/multiply.php",
|
||||
"classes/src/operations/divideby.php",
|
||||
"classes/src/operations/divideinto.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"time": "2018-07-31T08:38:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.23.0",
|
||||
@ -124,33 +219,59 @@
|
||||
},
|
||||
{
|
||||
"name": "pacificsec/cpe",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pacificsec/cpe.git",
|
||||
"reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11"
|
||||
"reference": "52cc49e04388ba00493be634287f6ce3efb30afc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pacificsec/cpe/zipball/3d78d66fc4ea249b6f353a7c48f426835a792d11",
|
||||
"reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11",
|
||||
"url": "https://api.github.com/repos/pacificsec/cpe/zipball/52cc49e04388ba00493be634287f6ce3efb30afc",
|
||||
"reference": "52cc49e04388ba00493be634287f6ce3efb30afc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"notification-url": "https://packagist.org/downloads/"
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PacificSec\\CPE\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Franco",
|
||||
"email": "antonio.franco@pacificsec.com"
|
||||
}
|
||||
],
|
||||
"description": "CPE: Common Platform Enumeration for PHP",
|
||||
"homepage": "https://github.com/pacificsec/cpe",
|
||||
"keywords": [
|
||||
"cpe",
|
||||
"cve",
|
||||
"pacificsec",
|
||||
"security"
|
||||
],
|
||||
"time": "2018-08-22T17:55:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.2.1",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "36acc372875c4d894dc093825ce4f62209db5a76"
|
||||
"reference": "125f462a718956f37d81305ca0df4f17cef0f3b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/36acc372875c4d894dc093825ce4f62209db5a76",
|
||||
"reference": "36acc372875c4d894dc093825ce4f62209db5a76",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/125f462a718956f37d81305ca0df4f17cef0f3b9",
|
||||
"reference": "125f462a718956f37d81305ca0df4f17cef0f3b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -166,6 +287,7 @@
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"markbaker/complex": "^1.4.1",
|
||||
"php": "^5.6|^7.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
@ -175,7 +297,7 @@
|
||||
"jpgraph/jpgraph": "^4.0",
|
||||
"mpdf/mpdf": "^7.0.0",
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "^2.7",
|
||||
"squizlabs/php_codesniffer": "^3.3",
|
||||
"tecnickcom/tcpdf": "^6.2"
|
||||
},
|
||||
"suggest": {
|
||||
@ -223,7 +345,7 @@
|
||||
"xls",
|
||||
"xlsx"
|
||||
],
|
||||
"time": "2018-04-10T03:53:16+00:00"
|
||||
"time": "2018-08-06T02:58:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
@ -322,16 +444,16 @@
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.2.17",
|
||||
"version": "6.2.22",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "64fc19439863e1b1314487a72a74d9bfd0b55a53"
|
||||
"reference": "ac6e92fccc7d9383dfd787056831349621b1aca2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/64fc19439863e1b1314487a72a74d9bfd0b55a53",
|
||||
"reference": "64fc19439863e1b1314487a72a74d9bfd0b55a53",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ac6e92fccc7d9383dfd787056831349621b1aca2",
|
||||
"reference": "ac6e92fccc7d9383dfd787056831349621b1aca2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -380,7 +502,7 @@
|
||||
"pdf417",
|
||||
"qrcode"
|
||||
],
|
||||
"time": "2018-02-24T11:48:20+00:00"
|
||||
"time": "2018-09-14T15:26:29+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -440,16 +562,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.8.0",
|
||||
"version": "1.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6"
|
||||
"reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/478465659fd987669df0bd8a9bf22a8710e5f1b6",
|
||||
"reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
|
||||
"reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -484,26 +606,26 @@
|
||||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"time": "2018-05-29T17:25:09+00:00"
|
||||
"time": "2018-06-11T23:09:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/manifest.git",
|
||||
"reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0"
|
||||
"reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0",
|
||||
"reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0",
|
||||
"url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
|
||||
"reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-phar": "*",
|
||||
"phar-io/version": "^1.0.1",
|
||||
"phar-io/version": "^2.0",
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
@ -539,20 +661,20 @@
|
||||
}
|
||||
],
|
||||
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
|
||||
"time": "2017-03-05T18:14:27+00:00"
|
||||
"time": "2018-07-08T19:23:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/version",
|
||||
"version": "1.0.1",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/version.git",
|
||||
"reference": "a70c0ced4be299a63d32fa96d9281d03e94041df"
|
||||
"reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df",
|
||||
"reference": "a70c0ced4be299a63d32fa96d9281d03e94041df",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
|
||||
"reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -586,7 +708,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Library for handling version information and constraints",
|
||||
"time": "2017-03-05T17:38:23+00:00"
|
||||
"time": "2018-07-08T19:19:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
@ -742,16 +864,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "1.7.6",
|
||||
"version": "1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712"
|
||||
"reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
|
||||
"reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
|
||||
"reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -763,12 +885,12 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.5|^3.2",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.7.x-dev"
|
||||
"dev-master": "1.8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -801,44 +923,44 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2018-04-18T13:57:24+00:00"
|
||||
"time": "2018-08-05T17:53:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "5.3.2",
|
||||
"version": "6.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "c89677919c5dd6d3b3852f230a663118762218ac"
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac",
|
||||
"reference": "c89677919c5dd6d3b3852f230a663118762218ac",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"reference": "865662550c384bc1db7e51d29aeda1c2c161d69a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"php": "^7.0",
|
||||
"phpunit/php-file-iterator": "^1.4.2",
|
||||
"php": "^7.1",
|
||||
"phpunit/php-file-iterator": "^2.0",
|
||||
"phpunit/php-text-template": "^1.2.1",
|
||||
"phpunit/php-token-stream": "^2.0.1",
|
||||
"phpunit/php-token-stream": "^3.0",
|
||||
"sebastian/code-unit-reverse-lookup": "^1.0.1",
|
||||
"sebastian/environment": "^3.0",
|
||||
"sebastian/environment": "^3.1",
|
||||
"sebastian/version": "^2.0.1",
|
||||
"theseer/tokenizer": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0"
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-xdebug": "^2.5.5"
|
||||
"ext-xdebug": "^2.6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.3.x-dev"
|
||||
"dev-master": "6.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -864,29 +986,32 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-04-06T15:36:58+00:00"
|
||||
"time": "2018-06-01T07:51:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
"version": "1.4.5",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
|
||||
"reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
|
||||
"reference": "050bedf145a257b1ff02746c31894800e5122946",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4.x-dev"
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -901,7 +1026,7 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
@ -911,7 +1036,7 @@
|
||||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2017-11-27T13:52:08+00:00"
|
||||
"time": "2018-09-13T20:33:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
@ -956,28 +1081,28 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
"version": "1.0.9",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
|
||||
"reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
||||
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
|
||||
"reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.3 || ^7.0"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -992,7 +1117,7 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
@ -1001,33 +1126,33 @@
|
||||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2017-02-26T11:10:40+00:00"
|
||||
"time": "2018-02-01T13:07:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "2.0.2",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "791198a2c6254db10131eecfe8c06670700904db"
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
|
||||
"reference": "791198a2c6254db10131eecfe8c06670700904db",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.0"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.2.4"
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1050,40 +1175,40 @@
|
||||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2017-11-27T05:48:46+00:00"
|
||||
"time": "2018-02-01T13:16:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "6.5.8",
|
||||
"version": "7.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b"
|
||||
"reference": "7b331efabbb628c518c408fdfcaf571156775de2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4f21a3c6b97c42952fd5c2837bb354ec0199b97b",
|
||||
"reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b331efabbb628c518c408fdfcaf571156775de2",
|
||||
"reference": "7b331efabbb628c518c408fdfcaf571156775de2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.1",
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-xml": "*",
|
||||
"myclabs/deep-copy": "^1.6.1",
|
||||
"phar-io/manifest": "^1.0.1",
|
||||
"phar-io/version": "^1.0",
|
||||
"php": "^7.0",
|
||||
"myclabs/deep-copy": "^1.7",
|
||||
"phar-io/manifest": "^1.0.2",
|
||||
"phar-io/version": "^2.0",
|
||||
"php": "^7.1",
|
||||
"phpspec/prophecy": "^1.7",
|
||||
"phpunit/php-code-coverage": "^5.3",
|
||||
"phpunit/php-file-iterator": "^1.4.3",
|
||||
"phpunit/php-code-coverage": "^6.0.7",
|
||||
"phpunit/php-file-iterator": "^2.0.1",
|
||||
"phpunit/php-text-template": "^1.2.1",
|
||||
"phpunit/php-timer": "^1.0.9",
|
||||
"phpunit/phpunit-mock-objects": "^5.0.5",
|
||||
"sebastian/comparator": "^2.1",
|
||||
"sebastian/diff": "^2.0",
|
||||
"phpunit/php-timer": "^2.0",
|
||||
"sebastian/comparator": "^3.0",
|
||||
"sebastian/diff": "^3.0",
|
||||
"sebastian/environment": "^3.1",
|
||||
"sebastian/exporter": "^3.1",
|
||||
"sebastian/global-state": "^2.0",
|
||||
@ -1092,15 +1217,15 @@
|
||||
"sebastian/version": "^2.0.1"
|
||||
},
|
||||
"conflict": {
|
||||
"phpdocumentor/reflection-docblock": "3.0.2",
|
||||
"phpunit/dbunit": "<3.0"
|
||||
"phpunit/phpunit-mock-objects": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*",
|
||||
"ext-xdebug": "*",
|
||||
"phpunit/php-invoker": "^1.1"
|
||||
"phpunit/php-invoker": "^2.0"
|
||||
},
|
||||
"bin": [
|
||||
"phpunit"
|
||||
@ -1108,7 +1233,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.5.x-dev"
|
||||
"dev-master": "7.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1134,66 +1259,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-04-10T11:38:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
"version": "5.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
||||
"reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3eaf040f20154d27d6da59ca2c6e28ac8fd56dce",
|
||||
"reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.5",
|
||||
"php": "^7.0",
|
||||
"phpunit/php-text-template": "^1.2.1",
|
||||
"sebastian/exporter": "^3.1"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "Mock Object library for PHPUnit",
|
||||
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
|
||||
"keywords": [
|
||||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2018-05-29T13:50:43+00:00"
|
||||
"time": "2018-09-08T15:14:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit-reverse-lookup",
|
||||
@ -1242,30 +1308,30 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"version": "2.1.3",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "34369daee48eafb2651bea869b4b15d75ccc35f9"
|
||||
"reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9",
|
||||
"reference": "34369daee48eafb2651bea869b4b15d75ccc35f9",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
|
||||
"reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0",
|
||||
"sebastian/diff": "^2.0 || ^3.0",
|
||||
"php": "^7.1",
|
||||
"sebastian/diff": "^3.0",
|
||||
"sebastian/exporter": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4"
|
||||
"phpunit/phpunit": "^7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1.x-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1302,32 +1368,33 @@
|
||||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"time": "2018-02-01T13:46:46+00:00"
|
||||
"time": "2018-07-12T15:12:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "2.0.1",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd"
|
||||
"reference": "366541b989927187c4ca70490a35615d3fef2dce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
|
||||
"reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
|
||||
"reference": "366541b989927187c4ca70490a35615d3fef2dce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0"
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.2"
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"symfony/process": "^2 || ^3.3 || ^4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1352,9 +1419,12 @@
|
||||
"description": "Diff implementation",
|
||||
"homepage": "https://github.com/sebastianbergmann/diff",
|
||||
"keywords": [
|
||||
"diff"
|
||||
"diff",
|
||||
"udiff",
|
||||
"unidiff",
|
||||
"unified diff"
|
||||
],
|
||||
"time": "2017-08-03T08:09:46+00:00"
|
||||
"time": "2018-06-10T07:54:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
|
143
inc/database.inc
@ -73,6 +73,7 @@
|
||||
* - May 31, 2018 - Changes to support renaming sagacity.pdi_catalog.check_content field and scan error detection
|
||||
* - Jun 2, 2018 - Formatting and added set_Setting_Array method
|
||||
* - Jun 5, 2018 - Changed set_Setting_Array method to use SQL update instead of replace
|
||||
* - Sep 5, 2018 - Fix for #8
|
||||
*/
|
||||
include_once 'base.inc';
|
||||
include_once 'software.inc';
|
||||
@ -1270,7 +1271,7 @@ class db_helper
|
||||
"Executing: $this->query_type\t" .
|
||||
"SQL: {$errmsg}" . PHP_EOL, FILE_APPEND);
|
||||
|
||||
if ($errno == E_DEBUG && $this->result && LOG_LEVEL == E_DEBUG) {
|
||||
if ($errno == E_DEBUG && $this->result && LOG_LEVEL == E_DEBUG && is_a($this->result, 'mysqli_result')) {
|
||||
file_put_contents(realpath(LOG_PATH . '/db.debug'), print_r($this->result, true), FILE_APPEND);
|
||||
}
|
||||
elseif ($errno == E_ERROR && $this->c->error) {
|
||||
@ -1695,7 +1696,7 @@ class db_helper
|
||||
|
||||
/**
|
||||
*
|
||||
* @return type
|
||||
* @return string
|
||||
*/
|
||||
public static function mysql_escape_string()
|
||||
{
|
||||
@ -2352,6 +2353,7 @@ class db
|
||||
{
|
||||
$ret = true;
|
||||
$fields = array('pdi_id', 'cce_id');
|
||||
$params = [];
|
||||
|
||||
if (is_array($cces)) {
|
||||
foreach ($cces as $cce) {
|
||||
@ -2784,7 +2786,7 @@ class db
|
||||
* @param integer $cat_id
|
||||
* Integer category ID to get the summary on
|
||||
*
|
||||
* @return NULL|array:targets,checklist,summary
|
||||
* @return NULL|array:targets,checklist,string
|
||||
* Returns an associative array of target (id & name), checklists, and a summary that joins the two
|
||||
*/
|
||||
public function get_Checklist_Summary($cat_id)
|
||||
@ -4102,7 +4104,7 @@ class db
|
||||
* Function to get the findings that are assigned to specific controls
|
||||
*
|
||||
* @param ste $ste
|
||||
* @param proc_ia_control $ia_ctrl
|
||||
* @param proc_ia_controls $ia_ctrl
|
||||
* @param string $status
|
||||
* @return array:finding |NULL
|
||||
*/
|
||||
@ -4258,7 +4260,7 @@ class db
|
||||
* The status to look for
|
||||
* @param integer $cat [optional]
|
||||
* The CAT/severity level
|
||||
* @param proc_ia_control $ctrl [optional]
|
||||
* @param proc_ia_controls $ctrl [optional]
|
||||
* A IA control to filter for
|
||||
*
|
||||
* @return integer
|
||||
@ -4312,7 +4314,7 @@ class db
|
||||
];
|
||||
}
|
||||
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_control')) {
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_controls')) {
|
||||
$where[] = [
|
||||
'field' => 'fc.ia_control',
|
||||
'value' => $ctrl->get_Control_ID(),
|
||||
@ -4333,7 +4335,7 @@ class db
|
||||
"JOIN sagacity.target t ON t.id=f.tgt_id"
|
||||
];
|
||||
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_control')) {
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_controls')) {
|
||||
$joins[] = "JOIN sagacity.finding_controls fc ON fc.finding_id=f.id";
|
||||
}
|
||||
|
||||
@ -4378,7 +4380,7 @@ class db
|
||||
];
|
||||
}
|
||||
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_control')) {
|
||||
if (!is_null($ctrl) && is_a($ctrl, 'proc_ia_controls')) {
|
||||
$where[] = [
|
||||
'field' => 'fc.ia_control',
|
||||
'value' => $ctrl->get_Control_ID(),
|
||||
@ -4403,7 +4405,7 @@ class db
|
||||
* The status to look for
|
||||
* @param integer $cat
|
||||
* The CAT/severity level
|
||||
* @param proc_ia_control $ctrl
|
||||
* @param proc_ia_controls $ctrl
|
||||
* A IA control to filter for
|
||||
*
|
||||
* @return integer
|
||||
@ -4460,7 +4462,7 @@ class db
|
||||
* The status to look for
|
||||
* @param integer $cat [optional]
|
||||
* The CAT/severity level
|
||||
* @param proc_ia_control $ctrl [optional]
|
||||
* @param proc_ia_controls $ctrl [optional]
|
||||
* A IA control to filter for
|
||||
* @param array $chk_ids [optional]
|
||||
* @param boolean $is_orphan [optional]
|
||||
@ -4470,7 +4472,6 @@ class db
|
||||
*/
|
||||
public function get_Host_Finding_Count_By_Status($tgt, $status, $cat = null, $ctrl = null, $chk_ids = null, $is_orphan = false)
|
||||
{
|
||||
$count = 0;
|
||||
if (!$is_orphan) {
|
||||
$sql = "SELECT (SELECT COUNT(DISTINCT(pcl.`pdi_id`)) " .
|
||||
"FROM `sagacity`.`target` t " .
|
||||
@ -4644,12 +4645,11 @@ class db
|
||||
* @TODO - FINISH
|
||||
*
|
||||
* @param ste $ste
|
||||
* @param proc_ia_control $ia_ctrl
|
||||
* @param proc_ia_controls $ia_ctrl
|
||||
* @param string $status
|
||||
*/
|
||||
public function get_Finding_Pervasivity_by_Control($ste, $ia_ctrl, $status = null)
|
||||
{
|
||||
$sql = "SELECT COUNT";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4851,7 +4851,7 @@ class db
|
||||
$updated_finding = [];
|
||||
$new_finding = [];
|
||||
$x = 0;
|
||||
foreach ($tgts as $key => $tgt) {
|
||||
foreach ($tgts as $tgt) {
|
||||
switch (strtolower(str_replace('_', ' ', $finding_data[self::FIRST_ECHECKLIST_HOST_COL + $x]))) {
|
||||
case 'not reviewed':
|
||||
case 'not a finding':
|
||||
@ -4991,7 +4991,7 @@ class db
|
||||
$notes = (isset($current_finding) && is_array($current_finding) && count($current_finding) ? $current_finding->get_Notes() . " " . $notes : $notes);
|
||||
|
||||
if (isset($updated_finding) && is_array($updated_finding) && count($updated_finding) > 0) {
|
||||
foreach ($updated_finding as $key => $finding) {
|
||||
foreach ($updated_finding as $finding) {
|
||||
$update_sql = "UPDATE `findings` SET " .
|
||||
"`scan_id` = " . $this->conn->real_escape_string($finding->get_Scan_ID()) . ", " .
|
||||
"`findings_status_id` = " . $this->conn->real_escape_string($finding->get_Finding_Status()) . ", " .
|
||||
@ -5007,13 +5007,13 @@ class db
|
||||
if (!$this->conn->real_query($update_sql)) {
|
||||
Sagacity_Error::sql_handler($update_sql);
|
||||
error_log($this->conn->error);
|
||||
$ret = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->conn->real_query("DELETE FROM `finding_controls` WHERE `finding_id` = " . $finding->get_ID());
|
||||
|
||||
$sql2 = "INSERT INTO `finding_controls` (`finding_id`, `ia_control`) VALUES ";
|
||||
foreach ($finding->get_IA_Controls() as $key => $ia) {
|
||||
foreach ($finding->get_IA_Controls() as $ia) {
|
||||
$sql2 .= "({$this->conn->real_escape_string($finding->get_ID())}, " .
|
||||
"'{$this->conn->real_escape_string($ia)}'),";
|
||||
}
|
||||
@ -5025,7 +5025,7 @@ class db
|
||||
}
|
||||
|
||||
if (isset($new_finding) && count($new_finding) > 0) {
|
||||
foreach ($new_finding as $key => $finding) {
|
||||
foreach ($new_finding as $finding) {
|
||||
$insert_sql = "INSERT INTO `findings` (`tgt_id`, `pdi_id`, `scan_id`, `findings_status_id`, `cat`, `notes`) VALUES " .
|
||||
"(" . $this->conn->real_escape_string($finding->get_Tgt_ID()) . ", " .
|
||||
$this->conn->real_escape_string($finding->get_PDI_ID()) . ", " .
|
||||
@ -5040,14 +5040,14 @@ class db
|
||||
if (!$this->conn->real_query($insert_sql)) {
|
||||
Sagacity_Error::sql_handler($insert_sql);
|
||||
error_log($this->conn->error);
|
||||
$ret = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$find_id = $this->conn->insert_id;
|
||||
|
||||
$sql2 = "INSERT INTO `finding_controls` (`finding_id`, `ia_control`) VALUES ";
|
||||
foreach ($finding->get_IA_Controls() as $key => $ia) {
|
||||
foreach ($finding->get_IA_Controls() as $ia) {
|
||||
$sql2 .= "({$this->conn->real_escape_string($find_id)}, " .
|
||||
"'{$this->conn->real_escape_string($ia)}'),";
|
||||
}
|
||||
@ -5170,14 +5170,14 @@ class db
|
||||
if (!$this->conn->real_query($update_sql)) {
|
||||
Sagacity_Error::sql_handler($update_sql);
|
||||
error_log($this->conn->error);
|
||||
$ret = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->conn->real_query("DELETE FROM `sagacity`.`finding_controls` WHERE `finding_id` = " . $updated_finding->get_ID());
|
||||
|
||||
$sql2 = "INSERT INTO `sagacity`.`finding_controls` (`finding_id`, `ia_control`) VALUES ";
|
||||
|
||||
foreach ($updated_finding->get_IA_Controls() as $key => $ia) {
|
||||
foreach ($updated_finding->get_IA_Controls() as $ia) {
|
||||
$sql2 .= "(" .
|
||||
$this->conn->real_escape_string($updated_finding->get_ID()) . ", " .
|
||||
"'" . $this->conn->real_escape_string($ia) . "'), ";
|
||||
@ -5203,14 +5203,14 @@ class db
|
||||
if (!$this->conn->real_query($insert_sql)) {
|
||||
Sagacity_Error::sql_handler($insert_sql);
|
||||
error_log($this->conn->error);
|
||||
$ret = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$find_id = $this->conn->insert_id;
|
||||
|
||||
$sql2 = "INSERT INTO `sagacity`.`finding_controls` (`finding_id`, `ia_control`) VALUES ";
|
||||
foreach ($new_finding->get_IA_Controls() as $key => $ia) {
|
||||
foreach ($new_finding->get_IA_Controls() as $ia) {
|
||||
$sql2 .= "(" .
|
||||
$this->conn->real_escape_string($find_id) . ", " .
|
||||
"'" . $this->conn->real_escape_string($ia) . "'), ";
|
||||
@ -5728,7 +5728,7 @@ class db
|
||||
* Function to get the icon that represents the IA control status
|
||||
*
|
||||
* @param ste $ste
|
||||
* @param proc_ia_control $ctrl
|
||||
* @param proc_ia_controls $ctrl
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -5747,7 +5747,7 @@ class db
|
||||
}
|
||||
|
||||
if (false) {
|
||||
$ctrl = new proc_ia_control();
|
||||
$ctrl = new proc_ia_controls();
|
||||
}
|
||||
if (empty($ctrl->finding->vul_desc)) {
|
||||
return "exclamation.png";
|
||||
@ -6250,7 +6250,7 @@ class db
|
||||
* @param integer $tgt_id
|
||||
* @param string $ip
|
||||
*
|
||||
* @return NULL|interface
|
||||
* @return NULL|interfaces
|
||||
*/
|
||||
public function get_Interface_By_IP($tgt_id, $ip)
|
||||
{
|
||||
@ -6554,7 +6554,7 @@ class db
|
||||
array(
|
||||
'field' => 'int_id',
|
||||
'op' => '=',
|
||||
'value' => $id
|
||||
'value' => $int_id
|
||||
)
|
||||
));
|
||||
$this->help->execute();
|
||||
@ -6562,7 +6562,7 @@ class db
|
||||
array(
|
||||
'field' => 'id',
|
||||
'op' => '=',
|
||||
'value' => $id
|
||||
'value' => $int_id
|
||||
)
|
||||
));
|
||||
$this->help->execute();
|
||||
@ -6632,7 +6632,7 @@ class db
|
||||
$ret = true;
|
||||
$ins_sql = 'REPLACE INTO `sagacity`.`pps_list` (`int_id`,`pps_id`,`name`,`banner`,`notes`) VALUES ';
|
||||
if ($action == 'insert') {
|
||||
foreach ($ports as $key => $port) {
|
||||
foreach ($ports as $port) {
|
||||
$ins_sql .= "(" . $int->get_ID() . ", " .
|
||||
"(SELECT `id` FROM `sagacity`.`ports_proto_services` WHERE `port` = '" . $port->get_Port() . "'" .
|
||||
" AND `proto` = '" . (is_a($port, 'tcp_ports') ? 'tcp' : 'udp') . "' " .
|
||||
@ -6673,10 +6673,12 @@ class db
|
||||
public function get_TCP_Ports($port_number = null)
|
||||
{
|
||||
$ret = [];
|
||||
$where[] = [
|
||||
$where = [
|
||||
[
|
||||
'field' => 'proto',
|
||||
'op' => '=',
|
||||
'value' => 'tcp'
|
||||
]
|
||||
];
|
||||
|
||||
if (!is_null($port_number)) {
|
||||
@ -6719,10 +6721,12 @@ class db
|
||||
public function get_UDP_Ports($port_number = null)
|
||||
{
|
||||
$ret = [];
|
||||
$where[] = [
|
||||
$where = [
|
||||
[
|
||||
'field' => 'proto',
|
||||
'op' => '=',
|
||||
'value' => 'udp'
|
||||
]
|
||||
];
|
||||
|
||||
if (!is_null($port_number)) {
|
||||
@ -7088,13 +7092,14 @@ class db
|
||||
|
||||
while ($sth->fetch()) {
|
||||
$x++;
|
||||
$ret = preg_match('/Registry Hive: +(\S*)/', $check_contents, $match);
|
||||
$match = [];
|
||||
preg_match('/Registry Hive: +(\S*)/', $check_contents, $match);
|
||||
$hive = $match[1];
|
||||
|
||||
$ret = preg_match('/(Subkey|Path|Registry Path): +(\\\)?(.*)/', $check_contents, $match);
|
||||
preg_match('/(Subkey|Path|Registry Path): +(\\\)?(.*)/', $check_contents, $match);
|
||||
$path = is_array($match) && count($match) > 3 ? $match[3] : "STIG ID: $stig_id" . PHP_EOL;
|
||||
|
||||
$ret = preg_match('/Value Name: +(\S*)/', $check_contents, $match);
|
||||
preg_match('/Value Name: +(\S*)/', $check_contents, $match);
|
||||
$name = is_array($match) && count($match) > 1 ? $match[1] : '';
|
||||
|
||||
if (is_array($match) && count($match) == 2) {
|
||||
@ -7102,10 +7107,10 @@ class db
|
||||
$c_count = 1;
|
||||
}
|
||||
|
||||
$ret = preg_match('/Type: +(\S*)/', $check_contents, $match);
|
||||
preg_match('/Type: +(\S*)/', $check_contents, $match);
|
||||
$type = is_array($match) && count($match) > 0 ? $match[1] : "PDI ID: $pdi_id" . PHP_EOL;
|
||||
|
||||
$ret = preg_match('/Value: +(\S*)/', $check_contents, $match);
|
||||
preg_match('/Value: +(\S*)/', $check_contents, $match);
|
||||
$value = is_array($match) && count($match) > 0 ? $match[1] : "PDI ID: $pdi_id" . PHP_EOL;
|
||||
|
||||
if (strpos($type, "PDI ID: " . $pdi_id) !== false) {
|
||||
@ -7521,7 +7526,7 @@ class db
|
||||
}
|
||||
else {
|
||||
$cves = $nessus->get_Reference_By_Type('cve');
|
||||
foreach ($cves as $key => $cve_num) {
|
||||
foreach ($cves as $cve_num) {
|
||||
$cve = $this->get_CVE($cve_num);
|
||||
if ($cve->get_PDI_ID()) {
|
||||
return $cve->get_PDI_ID();
|
||||
@ -7544,7 +7549,7 @@ class db
|
||||
}
|
||||
|
||||
$bids = $nessus->get_Reference_By_Type('bid');
|
||||
foreach ($bids as $key => $bid_num) {
|
||||
foreach ($bids as $bid_num) {
|
||||
$sql = "SELECT iavm.`pdi_id` " .
|
||||
"FROM `sagacity`.`nessus_refs` nr " .
|
||||
"JOIN `sagacity`.`iavm_bids` ib ON ib.`bid`=nr.`val` " .
|
||||
@ -9259,7 +9264,7 @@ class db
|
||||
/**
|
||||
* Function to retrieve a software item by using the CPE or CPE v2.3
|
||||
*
|
||||
* @param strinig $cpe_in
|
||||
* @param string $cpe_in
|
||||
* CPE to search for
|
||||
*
|
||||
* @return software|NULL
|
||||
@ -10734,11 +10739,11 @@ class db
|
||||
public function get_Target_Details($int_STE_ID, $TGT = null)
|
||||
{
|
||||
$ret = [];
|
||||
$where[] = [
|
||||
$where = [[
|
||||
'field' => 't.ste_id',
|
||||
'op' => '=',
|
||||
'value' => $int_STE_ID
|
||||
];
|
||||
]];
|
||||
|
||||
if (!is_null($TGT)) {
|
||||
if (is_numeric($TGT)) {
|
||||
@ -10915,8 +10920,7 @@ class db
|
||||
|
||||
if (is_array($rows) && count($rows) && isset($rows[0])) {
|
||||
foreach ($rows as $row) {
|
||||
$tgt = $this->get_Target_Details($cat->get_STE_ID(), $row['id'])[0];
|
||||
$ret[] = $tgt;
|
||||
$ret[] = $this->get_Target_Details($cat->get_STE_ID(), $row['id'])[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -11065,7 +11069,7 @@ class db
|
||||
"SELECT {$tgt['id']},c.`id` FROM (" .
|
||||
"SELECT chk.*,s.`id` AS 'real_sw' " .
|
||||
"FROM `checklist` chk " .
|
||||
"JOIN `checklist_software_lookup` csl ON csl.`chk_id`=chk`.id` " .
|
||||
"JOIN `checklist_software_lookup` csl ON csl.`chk_id`=chk.`id` " .
|
||||
"JOIN `software` s ON csl.`sw_id`=s.`id` " .
|
||||
"WHERE " .
|
||||
"chk.`type` = 'manual' AND " .
|
||||
@ -11092,6 +11096,7 @@ class db
|
||||
elseif (strtolower($os->man) == 'microsoft' && strtolower($os->name) == 'windows 7') {
|
||||
$sw = "Win7";
|
||||
}
|
||||
$this->help->query_type = db_helper::INSERT;
|
||||
$this->help->sql = "INSERT IGNORE INTO `target_checklist` (`tgt_id`,`chk_id`) " .
|
||||
"SELECT '{$tgt['id']}',c.`id` FROM (" .
|
||||
"SELECT chk.*,s.`id` as 'real_sw' " .
|
||||
@ -11113,6 +11118,7 @@ class db
|
||||
if (strtolower($os->man) == 'microsoft') {
|
||||
$sw = "Windows";
|
||||
}
|
||||
$this->help->query_type = db_helper::INSERT;
|
||||
$this->help->sql = "INSERT IGNORE INTO `target_checklist` (`tgt_id`,`chk_id`) " .
|
||||
"SELECT '{$tgt['id']}',c.`id` FROM (" .
|
||||
"SELECT chk.*,s.`id` AS 'real_sw' " .
|
||||
@ -11129,6 +11135,7 @@ class db
|
||||
;
|
||||
$this->help->execute();
|
||||
|
||||
$this->help->query_type = db_helper::INSERT;
|
||||
$this->help->sql = "INSERT IGNORE INTO `target_checklist` (`tgt_id`,`chk_id`) " .
|
||||
"SELECT '{$tgt['id']}',c.`id` FROM (" .
|
||||
"SELECT chk.*,csl.`sw_id` AS 'real_sw' FROM `checklist` chk " .
|
||||
@ -11151,12 +11158,15 @@ class db
|
||||
]);
|
||||
$this->help->execute();
|
||||
|
||||
$this->help->query_type = db_helper::INSERT;
|
||||
$this->help->sql = "INSERT IGNORE INTO `findings` (`tgt_id`,`pdi_id`,`findings_status_id`) " .
|
||||
"SELECT {$tgt['id']},pcl.pdi_id,'1' " .
|
||||
"FROM target_checklist tc " .
|
||||
"JOIN pdi_checklist_lookup pcl ON pcl.checklist_id = tc.chk_id " .
|
||||
"WHERE tc.tgt_id = {$tgt['id']}";
|
||||
$this->help->execute();
|
||||
|
||||
$this->update_Target_Counts($tgt['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11302,6 +11312,8 @@ class db
|
||||
"JOIN pdi_checklist_lookup pcl ON pcl.checklist_id = tc.chk_id " .
|
||||
"WHERE tc.tgt_id = {$id}";
|
||||
$this->help->execute();
|
||||
|
||||
$this->update_Target_Counts($id);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -11310,9 +11322,9 @@ class db
|
||||
/**
|
||||
* Function to update the target finding counts
|
||||
*
|
||||
* @param target $tgt
|
||||
* @param int $tgt_id
|
||||
*/
|
||||
public function update_Target_Counts(target $tgt)
|
||||
public function update_Target_Counts($tgt_id)
|
||||
{
|
||||
$nf = 0;
|
||||
$nr = 0;
|
||||
@ -11321,24 +11333,43 @@ class db
|
||||
$cat_2 = 0;
|
||||
$cat_3 = 0;
|
||||
|
||||
$this->help->select("get_pdi_count", ['pdi_count'], [
|
||||
$this->help->select('target t', ["COUNT(DISTINCT(pcl.pdi_id)) AS 'pdi_count'"], [
|
||||
[
|
||||
'field' => 'id',
|
||||
'field' => 't.id',
|
||||
'op' => '=',
|
||||
'value' => $tgt->get_ID()
|
||||
'value' => $tgt_id
|
||||
]
|
||||
], [
|
||||
'table_joins' => [
|
||||
"LEFT JOIN target_checklist tc ON tc.tgt_id = t.id",
|
||||
"LEFT JOIN pdi_checklist_lookup pcl ON pcl.checklist_id = tc.chk_id",
|
||||
"LEFT JOIN findings f ON f.pdi_id = pcl.pdi_id AND f.tgt_id = t.id"
|
||||
],
|
||||
'group' => 't.id'
|
||||
]);
|
||||
$row = $this->help->execute();
|
||||
if (is_array($row) && count($row) && isset($row['pdi_count'])) {
|
||||
$nr = $row['pdi_count'];
|
||||
}
|
||||
|
||||
$this->help->select("get_finding_count", ['status', 'severity', 'finding_count'], [
|
||||
$this->help->select("target t", [
|
||||
"IF(ISNULL(fs.status), 'Not Reviewed', fs.status) AS 'status'",
|
||||
"f.cat AS 'severity'",
|
||||
"COUNT(DISTINCT f.pdi_id) AS 'finding_count'"
|
||||
], [
|
||||
[
|
||||
'field' => 'id',
|
||||
'field' => 't.id',
|
||||
'op' => '=',
|
||||
'value' => $tgt->get_ID()
|
||||
'value' => $tgt_id
|
||||
]
|
||||
], [
|
||||
'table_joins' => [
|
||||
"LEFT JOIN target_checklist tc ON tc.tgt_id = t.id",
|
||||
"LEFT JOIN pdi_checklist_lookup pcl ON tc.chk_id = pcl.checklist_id",
|
||||
"LEFT JOIN findings f ON f.tgt_id = t.id AND f.pdi_id = pcl.pdi_id",
|
||||
"LEFT JOIN findings_status fs ON f.findings_status_id = fs.id"
|
||||
],
|
||||
'group' => "t.id,`severity`,f.findings_status_id"
|
||||
]);
|
||||
$rows = $this->help->execute();
|
||||
|
||||
@ -11392,7 +11423,7 @@ class db
|
||||
[
|
||||
'field' => 'id',
|
||||
'op' => '=',
|
||||
'value' => $tgt->get_ID()
|
||||
'value' => $tgt_id
|
||||
]
|
||||
]);
|
||||
$this->help->execute();
|
||||
@ -11609,8 +11640,6 @@ class db
|
||||
$this->help->debug(E_WARNING);
|
||||
}
|
||||
|
||||
$this->update_Target_Counts($tgt);
|
||||
|
||||
return $tgt->get_ID();
|
||||
}
|
||||
|
||||
@ -12218,7 +12247,7 @@ class db
|
||||
}
|
||||
$int_ids = $tmp;
|
||||
}
|
||||
if (count($int_ids)) {
|
||||
if (is_array($int_ids) && count($int_ids)) {
|
||||
$this->help->delete("pps_list", null, [
|
||||
[
|
||||
'field' => 'int_id',
|
||||
|
@ -353,10 +353,16 @@ $conditions['not_reviewed_count']->getStyle()
|
||||
->setEndColor($yellow);
|
||||
|
||||
$validation['host_status']->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
|
||||
$validation['host_status']->setFormula1("=ValidStatus");
|
||||
$validation['host_status']->setAllowBlank(false);
|
||||
$validation['host_status']->setFormula1('"Not Reviewed,Not a Finding,Open,Not Applicable,No Data,Exception,False Positive"');
|
||||
$validation['host_status']->setShowDropDown(true);
|
||||
$validation['host_status']->setShowErrorMessage(true);
|
||||
$validation['host_status']->setError("Selected value not valid");
|
||||
$validation['host_status']->setErrorTitle("Invalid selection");
|
||||
$validation['host_status']->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_STOP);
|
||||
|
||||
$validation['true_false']->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
|
||||
$validation['true_false']->setAllowBlank(false);
|
||||
$validation['true_false']->setFormula1("=TRUE,FALSE");
|
||||
$validation['true_false']->setShowDropDown(true);
|
||||
|
||||
|
@ -190,7 +190,7 @@ if (!$nasl['nasl-count']) {
|
||||
}
|
||||
|
||||
if (reload) {
|
||||
setTimeout(getLoadStatus, 1000);
|
||||
setTimeout(getLoadStatus, <?php print UPDATE_FREQ * 1000; ?>);
|
||||
}
|
||||
else {
|
||||
$('#db-err').remove();
|
||||
|
@ -42,6 +42,9 @@
|
||||
*/
|
||||
include_once 'error.inc';
|
||||
include_once 'validation.inc';
|
||||
include_once 'vendor/autoload.php';
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Function to get element or value from XML document using XPath
|
||||
@ -122,6 +125,7 @@ function getValue($xml, $path, $starting = null, $keep = false)
|
||||
*/
|
||||
function FileDetection($filename)
|
||||
{
|
||||
$name = [];
|
||||
$name['base_name'] = basename($filename);
|
||||
// print "\tCheck if exists".PHP_EOL;
|
||||
if (!file_exists($filename)) {
|
||||
@ -720,9 +724,9 @@ function url_exists($url)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $start
|
||||
* @param type $end
|
||||
* @return type
|
||||
* @param float $start
|
||||
* @param float $end
|
||||
* @return float
|
||||
*/
|
||||
function microtime_diff($start, $end = null)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ class BackgroundProcess {
|
||||
/**
|
||||
* @param int $pid PID of process to resume
|
||||
*
|
||||
* @return Cocur\BackgroundProcess\BackgroundProcess
|
||||
* @return BackgroundProcess
|
||||
*/
|
||||
static public function createFromPID($pid) {
|
||||
$process = new self();
|
||||
|
43
inc/vendor/composer/autoload_files.php
vendored
@ -6,5 +6,46 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'abede361264e2ae69ec1eee813a101af' => $vendorDir . '/markbaker/complex/classes/src/functions/abs.php',
|
||||
'21a5860fbef5be28db5ddfbc3cca67c4' => $vendorDir . '/markbaker/complex/classes/src/functions/acos.php',
|
||||
'1546e3f9d127f2a9bb2d1b6c31c26ef1' => $vendorDir . '/markbaker/complex/classes/src/functions/acosh.php',
|
||||
'd2516f7f4fba5ea5905f494b4a8262e0' => $vendorDir . '/markbaker/complex/classes/src/functions/acot.php',
|
||||
'4511163d560956219b96882c0980b65e' => $vendorDir . '/markbaker/complex/classes/src/functions/acoth.php',
|
||||
'c361f5616dc2a8da4fa3e137077cd4ea' => $vendorDir . '/markbaker/complex/classes/src/functions/acsc.php',
|
||||
'02d68920fc98da71991ce569c91df0f6' => $vendorDir . '/markbaker/complex/classes/src/functions/acsch.php',
|
||||
'88e19525eae308b4a6aa3419364875d3' => $vendorDir . '/markbaker/complex/classes/src/functions/argument.php',
|
||||
'60e8e2d0827b58bfc904f13957e51849' => $vendorDir . '/markbaker/complex/classes/src/functions/asec.php',
|
||||
'13d2f040713999eab66c359b4d79871d' => $vendorDir . '/markbaker/complex/classes/src/functions/asech.php',
|
||||
'838ab38beb32c68a79d3cd2c007d5a04' => $vendorDir . '/markbaker/complex/classes/src/functions/asin.php',
|
||||
'bb28eccd0f8f008333a1b3c163d604ac' => $vendorDir . '/markbaker/complex/classes/src/functions/asinh.php',
|
||||
'9e483de83558c98f7d3feaa402c78cb3' => $vendorDir . '/markbaker/complex/classes/src/functions/atan.php',
|
||||
'36b74b5b765ded91ee58c8ee3c0e85e3' => $vendorDir . '/markbaker/complex/classes/src/functions/atanh.php',
|
||||
'05c15ee9510da7fd6bf6136f436500c0' => $vendorDir . '/markbaker/complex/classes/src/functions/conjugate.php',
|
||||
'd3208dfbce2505e370788f9f22f6785f' => $vendorDir . '/markbaker/complex/classes/src/functions/cos.php',
|
||||
'141cf1fb3a3046f8b64534b0ebab33ca' => $vendorDir . '/markbaker/complex/classes/src/functions/cosh.php',
|
||||
'be660df75fd0dbe7fa7c03b7434b3294' => $vendorDir . '/markbaker/complex/classes/src/functions/cot.php',
|
||||
'01e31ea298a51bc9e91517e3ce6b9e76' => $vendorDir . '/markbaker/complex/classes/src/functions/coth.php',
|
||||
'803ddd97f7b1da68982a7b087c3476f6' => $vendorDir . '/markbaker/complex/classes/src/functions/csc.php',
|
||||
'3001cdfd101ec3c32da34ee43c2e149b' => $vendorDir . '/markbaker/complex/classes/src/functions/csch.php',
|
||||
'77b2d7629ef2a93fabb8c56754a91051' => $vendorDir . '/markbaker/complex/classes/src/functions/exp.php',
|
||||
'4a4471296dec796c21d4f4b6552396a9' => $vendorDir . '/markbaker/complex/classes/src/functions/inverse.php',
|
||||
'c3e9897e1744b88deb56fcdc39d34d85' => $vendorDir . '/markbaker/complex/classes/src/functions/ln.php',
|
||||
'a83cacf2de942cff288de15a83afd26d' => $vendorDir . '/markbaker/complex/classes/src/functions/log2.php',
|
||||
'6a861dacc9ee2f3061241d4c7772fa21' => $vendorDir . '/markbaker/complex/classes/src/functions/log10.php',
|
||||
'4d2522d968c8ba78d6c13548a1b4200e' => $vendorDir . '/markbaker/complex/classes/src/functions/negative.php',
|
||||
'fd587ca933fc0447fa5ab4843bdd97f7' => $vendorDir . '/markbaker/complex/classes/src/functions/pow.php',
|
||||
'383ef01c62028fc78cd4388082fce3c2' => $vendorDir . '/markbaker/complex/classes/src/functions/rho.php',
|
||||
'150fbd1b95029dc47292da97ecab9375' => $vendorDir . '/markbaker/complex/classes/src/functions/sec.php',
|
||||
'549abd9bae174286d660bdaa07407c68' => $vendorDir . '/markbaker/complex/classes/src/functions/sech.php',
|
||||
'6bfbf5eaea6b17a0ed85cb21ba80370c' => $vendorDir . '/markbaker/complex/classes/src/functions/sin.php',
|
||||
'22efe13f1a497b8e199540ae2d9dc59c' => $vendorDir . '/markbaker/complex/classes/src/functions/sinh.php',
|
||||
'e90135ab8e787795a509ed7147de207d' => $vendorDir . '/markbaker/complex/classes/src/functions/sqrt.php',
|
||||
'bb0a7923ffc6a90919cd64ec54ff06bc' => $vendorDir . '/markbaker/complex/classes/src/functions/tan.php',
|
||||
'2d302f32ce0fd4e433dd91c5bb404a28' => $vendorDir . '/markbaker/complex/classes/src/functions/tanh.php',
|
||||
'24dd4658a952171a4ee79218c4f9fd06' => $vendorDir . '/markbaker/complex/classes/src/functions/theta.php',
|
||||
'e49b7876281d6f5bc39536dde96d1f4a' => $vendorDir . '/markbaker/complex/classes/src/operations/add.php',
|
||||
'47596e02b43cd6da7700134fd08f88cf' => $vendorDir . '/markbaker/complex/classes/src/operations/subtract.php',
|
||||
'883af48563631547925fa4c3b48ead07' => $vendorDir . '/markbaker/complex/classes/src/operations/multiply.php',
|
||||
'f190e3308e6ca23234a2875edc985c03' => $vendorDir . '/markbaker/complex/classes/src/operations/divideby.php',
|
||||
'ac9e33ce6841aa5bf5d16d465a2f03a7' => $vendorDir . '/markbaker/complex/classes/src/operations/divideinto.php',
|
||||
);
|
||||
|
2
inc/vendor/composer/autoload_psr4.php
vendored
@ -9,6 +9,8 @@ return array(
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
|
||||
'PacificSec\\CPE\\' => array($vendorDir . '/pacificsec/cpe/src'),
|
||||
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
|
||||
'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'),
|
||||
'Cocur\\BackgroundProcess\\' => array($vendorDir . '/cocur/background-process/src'),
|
||||
);
|
||||
|
18
inc/vendor/composer/autoload_real.php
vendored
@ -47,6 +47,24 @@ class ComposerAutoloaderInit69a0c53551ee5f4e61c53efb549e5e72
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire69a0c53551ee5f4e61c53efb549e5e72($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire69a0c53551ee5f4e61c53efb549e5e72($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
|
55
inc/vendor/composer/autoload_static.php
vendored
@ -6,12 +6,58 @@ namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72
|
||||
{
|
||||
public static $files = array (
|
||||
'abede361264e2ae69ec1eee813a101af' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/abs.php',
|
||||
'21a5860fbef5be28db5ddfbc3cca67c4' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acos.php',
|
||||
'1546e3f9d127f2a9bb2d1b6c31c26ef1' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acosh.php',
|
||||
'd2516f7f4fba5ea5905f494b4a8262e0' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acot.php',
|
||||
'4511163d560956219b96882c0980b65e' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acoth.php',
|
||||
'c361f5616dc2a8da4fa3e137077cd4ea' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acsc.php',
|
||||
'02d68920fc98da71991ce569c91df0f6' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acsch.php',
|
||||
'88e19525eae308b4a6aa3419364875d3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/argument.php',
|
||||
'60e8e2d0827b58bfc904f13957e51849' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asec.php',
|
||||
'13d2f040713999eab66c359b4d79871d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asech.php',
|
||||
'838ab38beb32c68a79d3cd2c007d5a04' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asin.php',
|
||||
'bb28eccd0f8f008333a1b3c163d604ac' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asinh.php',
|
||||
'9e483de83558c98f7d3feaa402c78cb3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/atan.php',
|
||||
'36b74b5b765ded91ee58c8ee3c0e85e3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/atanh.php',
|
||||
'05c15ee9510da7fd6bf6136f436500c0' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/conjugate.php',
|
||||
'd3208dfbce2505e370788f9f22f6785f' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cos.php',
|
||||
'141cf1fb3a3046f8b64534b0ebab33ca' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cosh.php',
|
||||
'be660df75fd0dbe7fa7c03b7434b3294' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cot.php',
|
||||
'01e31ea298a51bc9e91517e3ce6b9e76' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/coth.php',
|
||||
'803ddd97f7b1da68982a7b087c3476f6' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/csc.php',
|
||||
'3001cdfd101ec3c32da34ee43c2e149b' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/csch.php',
|
||||
'77b2d7629ef2a93fabb8c56754a91051' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/exp.php',
|
||||
'4a4471296dec796c21d4f4b6552396a9' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/inverse.php',
|
||||
'c3e9897e1744b88deb56fcdc39d34d85' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/ln.php',
|
||||
'a83cacf2de942cff288de15a83afd26d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/log2.php',
|
||||
'6a861dacc9ee2f3061241d4c7772fa21' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/log10.php',
|
||||
'4d2522d968c8ba78d6c13548a1b4200e' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/negative.php',
|
||||
'fd587ca933fc0447fa5ab4843bdd97f7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/pow.php',
|
||||
'383ef01c62028fc78cd4388082fce3c2' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/rho.php',
|
||||
'150fbd1b95029dc47292da97ecab9375' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sec.php',
|
||||
'549abd9bae174286d660bdaa07407c68' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sech.php',
|
||||
'6bfbf5eaea6b17a0ed85cb21ba80370c' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sin.php',
|
||||
'22efe13f1a497b8e199540ae2d9dc59c' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sinh.php',
|
||||
'e90135ab8e787795a509ed7147de207d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sqrt.php',
|
||||
'bb0a7923ffc6a90919cd64ec54ff06bc' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/tan.php',
|
||||
'2d302f32ce0fd4e433dd91c5bb404a28' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/tanh.php',
|
||||
'24dd4658a952171a4ee79218c4f9fd06' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/theta.php',
|
||||
'e49b7876281d6f5bc39536dde96d1f4a' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/add.php',
|
||||
'47596e02b43cd6da7700134fd08f88cf' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/subtract.php',
|
||||
'883af48563631547925fa4c3b48ead07' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/multiply.php',
|
||||
'f190e3308e6ca23234a2875edc985c03' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideby.php',
|
||||
'ac9e33ce6841aa5bf5d16d465a2f03a7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideinto.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\SimpleCache\\' => 16,
|
||||
'Psr\\Log\\' => 8,
|
||||
'PhpOffice\\PhpSpreadsheet\\' => 25,
|
||||
'PacificSec\\CPE\\' => 15,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
@ -19,6 +65,7 @@ class ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72
|
||||
),
|
||||
'C' =>
|
||||
array (
|
||||
'Complex\\' => 8,
|
||||
'Cocur\\BackgroundProcess\\' => 24,
|
||||
),
|
||||
);
|
||||
@ -36,10 +83,18 @@ class ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet',
|
||||
),
|
||||
'PacificSec\\CPE\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/pacificsec/cpe/src',
|
||||
),
|
||||
'Monolog\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
|
||||
),
|
||||
'Complex\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/markbaker/complex/classes/src',
|
||||
),
|
||||
'Cocur\\BackgroundProcess\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/cocur/background-process/src',
|
||||
|
164
inc/vendor/composer/installed.json
vendored
@ -39,6 +39,103 @@
|
||||
"unix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "1.4.6",
|
||||
"version_normalized": "1.4.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
|
||||
"reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6.0|^7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
|
||||
"phpcompatibility/php-compatibility": "^8.0",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "2.*",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.0",
|
||||
"sebastian/phpcpd": "2.*",
|
||||
"squizlabs/php_codesniffer": "^3.3.0"
|
||||
},
|
||||
"time": "2018-07-31T08:38:40+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
},
|
||||
"files": [
|
||||
"classes/src/functions/abs.php",
|
||||
"classes/src/functions/acos.php",
|
||||
"classes/src/functions/acosh.php",
|
||||
"classes/src/functions/acot.php",
|
||||
"classes/src/functions/acoth.php",
|
||||
"classes/src/functions/acsc.php",
|
||||
"classes/src/functions/acsch.php",
|
||||
"classes/src/functions/argument.php",
|
||||
"classes/src/functions/asec.php",
|
||||
"classes/src/functions/asech.php",
|
||||
"classes/src/functions/asin.php",
|
||||
"classes/src/functions/asinh.php",
|
||||
"classes/src/functions/atan.php",
|
||||
"classes/src/functions/atanh.php",
|
||||
"classes/src/functions/conjugate.php",
|
||||
"classes/src/functions/cos.php",
|
||||
"classes/src/functions/cosh.php",
|
||||
"classes/src/functions/cot.php",
|
||||
"classes/src/functions/coth.php",
|
||||
"classes/src/functions/csc.php",
|
||||
"classes/src/functions/csch.php",
|
||||
"classes/src/functions/exp.php",
|
||||
"classes/src/functions/inverse.php",
|
||||
"classes/src/functions/ln.php",
|
||||
"classes/src/functions/log2.php",
|
||||
"classes/src/functions/log10.php",
|
||||
"classes/src/functions/negative.php",
|
||||
"classes/src/functions/pow.php",
|
||||
"classes/src/functions/rho.php",
|
||||
"classes/src/functions/sec.php",
|
||||
"classes/src/functions/sech.php",
|
||||
"classes/src/functions/sin.php",
|
||||
"classes/src/functions/sinh.php",
|
||||
"classes/src/functions/sqrt.php",
|
||||
"classes/src/functions/tan.php",
|
||||
"classes/src/functions/tanh.php",
|
||||
"classes/src/functions/theta.php",
|
||||
"classes/src/operations/add.php",
|
||||
"classes/src/operations/subtract.php",
|
||||
"classes/src/operations/multiply.php",
|
||||
"classes/src/operations/divideby.php",
|
||||
"classes/src/operations/divideinto.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.23.0",
|
||||
@ -121,36 +218,62 @@
|
||||
},
|
||||
{
|
||||
"name": "pacificsec/cpe",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pacificsec/cpe.git",
|
||||
"reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11"
|
||||
"reference": "52cc49e04388ba00493be634287f6ce3efb30afc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pacificsec/cpe/zipball/3d78d66fc4ea249b6f353a7c48f426835a792d11",
|
||||
"reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11",
|
||||
"url": "https://api.github.com/repos/pacificsec/cpe/zipball/52cc49e04388ba00493be634287f6ce3efb30afc",
|
||||
"reference": "52cc49e04388ba00493be634287f6ce3efb30afc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2018-08-22T17:55:09+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"notification-url": "https://packagist.org/downloads/"
|
||||
"installation-source": "source",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PacificSec\\CPE\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Franco",
|
||||
"email": "antonio.franco@pacificsec.com"
|
||||
}
|
||||
],
|
||||
"description": "CPE: Common Platform Enumeration for PHP",
|
||||
"homepage": "https://github.com/pacificsec/cpe",
|
||||
"keywords": [
|
||||
"cpe",
|
||||
"cve",
|
||||
"pacificsec",
|
||||
"security"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.2.1",
|
||||
"version_normalized": "1.2.1.0",
|
||||
"version": "1.4.0",
|
||||
"version_normalized": "1.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "36acc372875c4d894dc093825ce4f62209db5a76"
|
||||
"reference": "125f462a718956f37d81305ca0df4f17cef0f3b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/36acc372875c4d894dc093825ce4f62209db5a76",
|
||||
"reference": "36acc372875c4d894dc093825ce4f62209db5a76",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/125f462a718956f37d81305ca0df4f17cef0f3b9",
|
||||
"reference": "125f462a718956f37d81305ca0df4f17cef0f3b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -166,6 +289,7 @@
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"markbaker/complex": "^1.4.1",
|
||||
"php": "^5.6|^7.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
@ -175,7 +299,7 @@
|
||||
"jpgraph/jpgraph": "^4.0",
|
||||
"mpdf/mpdf": "^7.0.0",
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "^2.7",
|
||||
"squizlabs/php_codesniffer": "^3.3",
|
||||
"tecnickcom/tcpdf": "^6.2"
|
||||
},
|
||||
"suggest": {
|
||||
@ -184,7 +308,7 @@
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
"tecnick.com/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||
},
|
||||
"time": "2018-04-10T03:53:16+00:00",
|
||||
"time": "2018-08-06T02:58:06+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "source",
|
||||
"autoload": {
|
||||
@ -327,23 +451,23 @@
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.2.17",
|
||||
"version_normalized": "6.2.17.0",
|
||||
"version": "6.2.22",
|
||||
"version_normalized": "6.2.22.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "64fc19439863e1b1314487a72a74d9bfd0b55a53"
|
||||
"reference": "ac6e92fccc7d9383dfd787056831349621b1aca2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/64fc19439863e1b1314487a72a74d9bfd0b55a53",
|
||||
"reference": "64fc19439863e1b1314487a72a74d9bfd0b55a53",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ac6e92fccc7d9383dfd787056831349621b1aca2",
|
||||
"reference": "ac6e92fccc7d9383dfd787056831349621b1aca2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2018-02-24T11:48:20+00:00",
|
||||
"time": "2018-09-14T15:26:29+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
|
155
inc/vendor/markbaker/complex/README.md
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
PHPComplex
|
||||
==========
|
||||
|
||||
---
|
||||
|
||||
PHP Class for handling Complex numbers
|
||||
|
||||
Master: [![Build Status](https://travis-ci.org/MarkBaker/PHPComplex.png?branch=master)](http://travis-ci.org/MarkBaker/PHPComplex)
|
||||
|
||||
Develop: [![Build Status](https://travis-ci.org/MarkBaker/PHPComplex.png?branch=develop)](http://travis-ci.org/MarkBaker/PHPComplex)
|
||||
|
||||
|
||||
---
|
||||
|
||||
The library currently provides the following operations:
|
||||
|
||||
- addition
|
||||
- subtraction
|
||||
- multiplication
|
||||
- division
|
||||
- division by
|
||||
- division into
|
||||
|
||||
together with functions for
|
||||
|
||||
- theta (polar theta angle)
|
||||
- rho (polar distance/radius)
|
||||
- conjugate
|
||||
* negative
|
||||
- inverse (1 / complex)
|
||||
- cos (cosine)
|
||||
- acos (inverse cosine)
|
||||
- cosh (hyperbolic cosine)
|
||||
- acosh (inverse hyperbolic cosine)
|
||||
- sin (sine)
|
||||
- asin (inverse sine)
|
||||
- sinh (hyperbolic sine)
|
||||
- asinh (inverse hyperbolic sine)
|
||||
- sec (secant)
|
||||
- asec (inverse secant)
|
||||
- sech (hyperbolic secant)
|
||||
- asech (inverse hyperbolic secant)
|
||||
- csc (cosecant)
|
||||
- acsc (inverse cosecant)
|
||||
- csch (hyperbolic secant)
|
||||
- acsch (inverse hyperbolic secant)
|
||||
- tan (tangent)
|
||||
- atan (inverse tangent)
|
||||
- tanh (hyperbolic tangent)
|
||||
- atanh (inverse hyperbolic tangent)
|
||||
- cot (cotangent)
|
||||
- acot (inverse cotangent)
|
||||
- coth (hyperbolic cotangent)
|
||||
- acoth (inverse hyperbolic cotangent)
|
||||
- sqrt (square root)
|
||||
- exp (exponential)
|
||||
- ln (natural log)
|
||||
- log10 (base-10 log)
|
||||
- log2 (base-2 log)
|
||||
- pow (raised to the power of a real number)
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Usage
|
||||
|
||||
To create a new complex object, you can provide either the real, imaginary and suffix parts as individual values, or as an array of values passed passed to the constructor; or a string representing the value. e.g
|
||||
|
||||
```
|
||||
$real = 1.23;
|
||||
$imaginary = -4.56;
|
||||
$suffix = 'i';
|
||||
|
||||
$complexObject = new Complex\Complex($real, $imaginary, $suffix);
|
||||
```
|
||||
or
|
||||
```
|
||||
$real = 1.23;
|
||||
$imaginary = -4.56;
|
||||
$suffix = 'i';
|
||||
|
||||
$arguments = [$real, $imaginary, $suffix];
|
||||
|
||||
$complexObject = new Complex\Complex($arguments);
|
||||
```
|
||||
or
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString);
|
||||
```
|
||||
|
||||
Complex objects are immutable: whenever you call a method or pass a complex value to a function that returns a complex value, a new Complex object will be returned, and the original will remain unchanged.
|
||||
This also allows you to chain multiple methods as you would for a fluent interface (as long as they are methods that will return a Complex result).
|
||||
|
||||
## Performing Mathematical Operations
|
||||
|
||||
To perform mathematical operations with Complex values, you can call the appropriate method against a complex value, passing other values as arguments
|
||||
|
||||
```
|
||||
$complexString1 = '1.23-4.56i';
|
||||
$complexString2 = '2.34+5.67i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString1);
|
||||
echo $complexObject->add($complexString2);
|
||||
```
|
||||
or pass all values to the appropriate function
|
||||
```
|
||||
$complexString1 = '1.23-4.56i';
|
||||
$complexString2 = '2.34+5.67i';
|
||||
|
||||
echo Complex\add($complexString1, $complexString2);
|
||||
```
|
||||
If you want to perform the same operation against multiple values (e.g. to add three or more complex numbers), then you can pass multiple arguments to any of the operations.
|
||||
|
||||
You can pass these arguments as Complex objects, or as an array or string that will parse to a complex object.
|
||||
|
||||
## Using functions
|
||||
|
||||
When calling any of the available functions for a complex value, you can either call the relevant method for the Complex object
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString);
|
||||
echo $complexObject->sinh();
|
||||
```
|
||||
or you can call the function as you would in procedural code, passing the Complex object as an argument
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString);
|
||||
echo Complex\sinh($complexObject);
|
||||
```
|
||||
When called procedurally using the function, you can pass in the argument as a Complex object, or as an array or string that will parse to a complex object.
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
echo Complex\sinh($complexString);
|
||||
```
|
||||
|
||||
In the case of the `pow()` function (the only implemented function that requires an additional argument) you need to pass both arguments when calling the function procedurally
|
||||
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString);
|
||||
echo Complex\pow($complexObject, 2);
|
||||
```
|
||||
or pass the additional argument when calling the method
|
||||
```
|
||||
$complexString = '1.23-4.56i';
|
||||
|
||||
$complexObject = new Complex\Complex($complexString);
|
||||
echo $complexObject->pow(2);
|
||||
```
|
53
inc/vendor/markbaker/complex/classes/Autoloader.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
*
|
||||
* Autoloader for Complex classes
|
||||
*
|
||||
* @package Complex
|
||||
* @copyright Copyright (c) 2014 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* Register the Autoloader with SPL
|
||||
*
|
||||
*/
|
||||
public static function Register()
|
||||
{
|
||||
if (function_exists('__autoload')) {
|
||||
// Register any existing autoloader function with SPL, so we don't get any clashes
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
// Register ourselves with SPL
|
||||
return spl_autoload_register(['Complex\Autoloader', 'Load']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Autoload a class identified by name
|
||||
*
|
||||
* @param string $pClassName Name of the object to load
|
||||
*/
|
||||
public static function Load($pClassName)
|
||||
{
|
||||
if ((class_exists($pClassName, false)) || (strpos($pClassName, 'Complex\\') !== 0)) {
|
||||
// Either already loaded, or not a Complex class request
|
||||
return false;
|
||||
}
|
||||
|
||||
$pClassFilePath = __DIR__ . DIRECTORY_SEPARATOR .
|
||||
'src' . DIRECTORY_SEPARATOR .
|
||||
str_replace('Complex\\', '', $pClassName) .
|
||||
'.php';
|
||||
|
||||
if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) {
|
||||
// Can't load
|
||||
return false;
|
||||
}
|
||||
require($pClassFilePath);
|
||||
}
|
||||
}
|
38
inc/vendor/markbaker/complex/classes/Bootstrap.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
include_once __DIR__ . '/Autoloader.php';
|
||||
|
||||
\Complex\Autoloader::Register();
|
||||
|
||||
|
||||
abstract class FilesystemRegexFilter extends RecursiveRegexIterator
|
||||
{
|
||||
protected $regex;
|
||||
public function __construct(RecursiveIterator $it, $regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
parent::__construct($it, $regex);
|
||||
}
|
||||
}
|
||||
|
||||
class FilenameFilter extends FilesystemRegexFilter
|
||||
{
|
||||
// Filter files against the regex
|
||||
public function accept()
|
||||
{
|
||||
return (!$this->isFile() || preg_match($this->regex, $this->getFilename()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$srcFolder = __DIR__ . DIRECTORY_SEPARATOR . 'src';
|
||||
$srcDirectory = new RecursiveDirectoryIterator($srcFolder);
|
||||
|
||||
$filteredFileList = new FilenameFilter($srcDirectory, '/(?:php)$/i');
|
||||
$filteredFileList = new FilenameFilter($filteredFileList, '/^(?!.*(Complex|Exception)\.php).*$/i');
|
||||
|
||||
foreach (new RecursiveIteratorIterator($filteredFileList) as $file) {
|
||||
if ($file->isFile()) {
|
||||
include_once $file;
|
||||
}
|
||||
}
|
387
inc/vendor/markbaker/complex/classes/src/Complex.php
vendored
Normal file
@ -0,0 +1,387 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the management of Complex numbers
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Complex Number object.
|
||||
*
|
||||
* @package Complex
|
||||
*
|
||||
* @method float abs()
|
||||
* @method Complex acos()
|
||||
* @method Complex acosh()
|
||||
* @method Complex acot()
|
||||
* @method Complex acoth()
|
||||
* @method Complex acsc()
|
||||
* @method Complex acsch()
|
||||
* @method float argument()
|
||||
* @method Complex asec()
|
||||
* @method Complex asech()
|
||||
* @method Complex asin()
|
||||
* @method Complex asinh()
|
||||
* @method Complex atan()
|
||||
* @method Complex atanh()
|
||||
* @method Complex conjugate()
|
||||
* @method Complex cos()
|
||||
* @method Complex cosh()
|
||||
* @method Complex cot()
|
||||
* @method Complex coth()
|
||||
* @method Complex csc()
|
||||
* @method Complex csch()
|
||||
* @method Complex exp()
|
||||
* @method Complex inverse()
|
||||
* @method Complex ln()
|
||||
* @method Complex log2()
|
||||
* @method Complex log10()
|
||||
* @method Complex negative()
|
||||
* @method Complex pow(int|float $power)
|
||||
* @method float rho()
|
||||
* @method Complex sec()
|
||||
* @method Complex sech()
|
||||
* @method Complex sin()
|
||||
* @method Complex sinh()
|
||||
* @method Complex sqrt()
|
||||
* @method Complex tan()
|
||||
* @method Complex tanh()
|
||||
* @method float theta()
|
||||
* @method Complex add(...$complexValues)
|
||||
* @method Complex subtract(...$complexValues)
|
||||
* @method Complex multiply(...$complexValues)
|
||||
* @method Complex divideby(...$complexValues)
|
||||
* @method Complex divideinto(...$complexValues)
|
||||
*/
|
||||
class Complex
|
||||
{
|
||||
/**
|
||||
* @constant Euler's Number.
|
||||
*/
|
||||
const EULER = 2.7182818284590452353602874713526624977572;
|
||||
|
||||
/**
|
||||
* @constant Regexp to split an input string into real and imaginary components and suffix
|
||||
*/
|
||||
const NUMBER_SPLIT_REGEXP =
|
||||
'` ^
|
||||
( # Real part
|
||||
[-+]?(\d+\.?\d*|\d*\.?\d+) # Real value (integer or float)
|
||||
([Ee][-+]?[0-2]?\d{1,3})? # Optional real exponent for scientific format
|
||||
)
|
||||
( # Imaginary part
|
||||
[-+]?(\d+\.?\d*|\d*\.?\d+) # Imaginary value (integer or float)
|
||||
([Ee][-+]?[0-2]?\d{1,3})? # Optional imaginary exponent for scientific format
|
||||
)?
|
||||
( # Imaginary part is optional
|
||||
([-+]?) # Imaginary (implicit 1 or -1) only
|
||||
([ij]?) # Imaginary i or j - depending on whether mathematical or engineering
|
||||
)
|
||||
$`uix';
|
||||
|
||||
/**
|
||||
* @var float $realPart The value of of this complex number on the real plane.
|
||||
*/
|
||||
protected $realPart = 0.0;
|
||||
|
||||
/**
|
||||
* @var float $imaginaryPart The value of of this complex number on the imaginary plane.
|
||||
*/
|
||||
protected $imaginaryPart = 0.0;
|
||||
|
||||
/**
|
||||
* @var string $suffix The suffix for this complex number (i or j).
|
||||
*/
|
||||
protected $suffix;
|
||||
|
||||
|
||||
/**
|
||||
* Validates whether the argument is a valid complex number, converting scalar or array values if possible
|
||||
*
|
||||
* @param mixed $complexNumber The value to parse
|
||||
* @return array
|
||||
* @throws Exception If the argument isn't a Complex number or cannot be converted to one
|
||||
*/
|
||||
private static function parseComplex($complexNumber)
|
||||
{
|
||||
// Test for real number, with no imaginary part
|
||||
if (is_numeric($complexNumber)) {
|
||||
return [$complexNumber, 0, null];
|
||||
}
|
||||
|
||||
// Fix silly human errors
|
||||
$complexNumber = str_replace(
|
||||
['+-', '-+', '++', '--'],
|
||||
['-', '-', '+', '+'],
|
||||
$complexNumber
|
||||
);
|
||||
|
||||
// Basic validation of string, to parse out real and imaginary parts, and any suffix
|
||||
$validComplex = preg_match(
|
||||
self::NUMBER_SPLIT_REGEXP,
|
||||
$complexNumber,
|
||||
$complexParts
|
||||
);
|
||||
|
||||
if (!$validComplex) {
|
||||
// Neither real nor imaginary part, so test to see if we actually have a suffix
|
||||
$validComplex = preg_match('/^([\-\+]?)([ij])$/ui', $complexNumber, $complexParts);
|
||||
if (!$validComplex) {
|
||||
throw new Exception('Invalid complex number');
|
||||
}
|
||||
// We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)
|
||||
$imaginary = 1;
|
||||
if ($complexParts[1] === '-') {
|
||||
$imaginary = 0 - $imaginary;
|
||||
}
|
||||
return [0, $imaginary, $complexParts[2]];
|
||||
}
|
||||
|
||||
// If we don't have an imaginary part, identify whether it should be +1 or -1...
|
||||
if (($complexParts[4] === '') && ($complexParts[9] !== '')) {
|
||||
if ($complexParts[7] !== $complexParts[9]) {
|
||||
$complexParts[4] = 1;
|
||||
if ($complexParts[8] === '-') {
|
||||
$complexParts[4] = -1;
|
||||
}
|
||||
} else {
|
||||
// ... or if we have only the real and no imaginary part
|
||||
// (in which case our real should be the imaginary)
|
||||
$complexParts[4] = $complexParts[1];
|
||||
$complexParts[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily
|
||||
return [
|
||||
$complexParts[1],
|
||||
$complexParts[4],
|
||||
!empty($complexParts[9]) ? $complexParts[9] : 'i'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function __construct($realPart = 0.0, $imaginaryPart = null, $suffix = 'i')
|
||||
{
|
||||
if ($imaginaryPart === null) {
|
||||
if (is_array($realPart)) {
|
||||
// We have an array of (potentially) real and imaginary parts, and any suffix
|
||||
list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + [0.0, 0.0, 'i'];
|
||||
} elseif ((is_string($realPart)) || (is_numeric($realPart))) {
|
||||
// We've been given a string to parse to extract the real and imaginary parts, and any suffix
|
||||
list($realPart, $imaginaryPart, $suffix) = self::parseComplex($realPart);
|
||||
}
|
||||
}
|
||||
if ($imaginaryPart <> 0.0 && empty($suffix)) {
|
||||
$suffix = 'i';
|
||||
}
|
||||
|
||||
// Set parsed values in our properties
|
||||
$this->realPart = (float) $realPart;
|
||||
$this->imaginaryPart = (float) $imaginaryPart;
|
||||
$this->suffix = strtolower($suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the real part of this complex number
|
||||
*
|
||||
* @return Float
|
||||
*/
|
||||
public function getReal()
|
||||
{
|
||||
return $this->realPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the imaginary part of this complex number
|
||||
*
|
||||
* @return Float
|
||||
*/
|
||||
public function getImaginary()
|
||||
{
|
||||
return $this->imaginaryPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the suffix of this complex number
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function getSuffix()
|
||||
{
|
||||
return $this->suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a real value, false if a complex value
|
||||
*
|
||||
* @return Bool
|
||||
*/
|
||||
public function isReal()
|
||||
{
|
||||
return $this->imaginaryPart == 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a complex value, false if a real value
|
||||
*
|
||||
* @return Bool
|
||||
*/
|
||||
public function isComplex()
|
||||
{
|
||||
return !$this->isReal();
|
||||
}
|
||||
|
||||
public function format()
|
||||
{
|
||||
$str = "";
|
||||
if ($this->imaginaryPart != 0.0) {
|
||||
if (\abs($this->imaginaryPart) != 1.0) {
|
||||
$str .= $this->imaginaryPart . $this->suffix;
|
||||
} else {
|
||||
$str .= (($this->imaginaryPart < 0.0) ? '-' : '') . $this->suffix;
|
||||
}
|
||||
}
|
||||
if ($this->realPart != 0.0) {
|
||||
if (($str) && ($this->imaginaryPart > 0.0)) {
|
||||
$str = "+" . $str;
|
||||
}
|
||||
$str = $this->realPart . $str;
|
||||
}
|
||||
if (!$str) {
|
||||
$str = "0.0";
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->format();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether the argument is a valid complex number, converting scalar or array values if possible
|
||||
*
|
||||
* @param mixed $complex The value to validate
|
||||
* @return Complex
|
||||
* @throws Exception If the argument isn't a Complex number or cannot be converted to one
|
||||
*/
|
||||
public static function validateComplexArgument($complex)
|
||||
{
|
||||
if (is_scalar($complex) || is_array($complex)) {
|
||||
$complex = new Complex($complex);
|
||||
} elseif (!is_object($complex) || !($complex instanceof Complex)) {
|
||||
throw new Exception('Value is not a valid complex number');
|
||||
}
|
||||
|
||||
return $complex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of this complex number
|
||||
*
|
||||
* @return Complex
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
return new Complex(
|
||||
$this->imaginaryPart,
|
||||
$this->realPart,
|
||||
($this->realPart == 0.0) ? null : $this->suffix
|
||||
);
|
||||
}
|
||||
|
||||
public function invertImaginary()
|
||||
{
|
||||
return new Complex(
|
||||
$this->realPart,
|
||||
$this->imaginaryPart * -1,
|
||||
($this->imaginaryPart == 0.0) ? null : $this->suffix
|
||||
);
|
||||
}
|
||||
|
||||
public function invertReal()
|
||||
{
|
||||
return new Complex(
|
||||
$this->realPart * -1,
|
||||
$this->imaginaryPart,
|
||||
($this->imaginaryPart == 0.0) ? null : $this->suffix
|
||||
);
|
||||
}
|
||||
|
||||
protected static $functions = [
|
||||
'abs',
|
||||
'acos',
|
||||
'acosh',
|
||||
'acot',
|
||||
'acoth',
|
||||
'acsc',
|
||||
'acsch',
|
||||
'argument',
|
||||
'asec',
|
||||
'asech',
|
||||
'asin',
|
||||
'asinh',
|
||||
'atan',
|
||||
'atanh',
|
||||
'conjugate',
|
||||
'cos',
|
||||
'cosh',
|
||||
'cot',
|
||||
'coth',
|
||||
'csc',
|
||||
'csch',
|
||||
'exp',
|
||||
'inverse',
|
||||
'ln',
|
||||
'log2',
|
||||
'log10',
|
||||
'negative',
|
||||
'pow',
|
||||
'rho',
|
||||
'sec',
|
||||
'sech',
|
||||
'sin',
|
||||
'sinh',
|
||||
'sqrt',
|
||||
'tan',
|
||||
'tanh',
|
||||
'theta',
|
||||
];
|
||||
|
||||
protected static $operations = [
|
||||
'add',
|
||||
'subtract',
|
||||
'multiply',
|
||||
'divideby',
|
||||
'divideinto',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the result of the function call or operation
|
||||
*
|
||||
* @return Complex|float
|
||||
* @throws Exception|\InvalidArgumentException
|
||||
*/
|
||||
public function __call($functionName, $arguments)
|
||||
{
|
||||
$functionName = strtolower(str_replace('_', '', $functionName));
|
||||
|
||||
// Test for function calls
|
||||
if (in_array($functionName, self::$functions)) {
|
||||
$functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
|
||||
return $functionName($this, ...$arguments);
|
||||
}
|
||||
// Test for operation calls
|
||||
if (in_array($functionName, self::$operations)) {
|
||||
$functionName = "\\" . __NAMESPACE__ . "\\{$functionName}";
|
||||
return $functionName($this, ...$arguments);
|
||||
}
|
||||
throw new Exception('Function or Operation does not exist');
|
||||
}
|
||||
}
|
13
inc/vendor/markbaker/complex/classes/src/Exception.php
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Exception.
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/abs.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex abs() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the absolute value (modulus) of a complex number.
|
||||
* Also known as the rho of the complex number, i.e. the distance/radius
|
||||
* from the centrepoint to the representation of the number in polar coordinates.
|
||||
*
|
||||
* This function is a synonym for rho()
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The absolute (or rho) value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*
|
||||
* @see rho
|
||||
*
|
||||
*/
|
||||
function abs($complex)
|
||||
{
|
||||
return rho($complex);
|
||||
}
|
38
inc/vendor/markbaker/complex/classes/src/functions/acos.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acos() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse cosine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse cosine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function acos($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$square = clone $complex;
|
||||
$square = multiply($square, $complex);
|
||||
$invsqrt = new Complex(1.0);
|
||||
$invsqrt = subtract($invsqrt, $square);
|
||||
$invsqrt = sqrt($invsqrt);
|
||||
$adjust = new Complex(
|
||||
$complex->getReal() - $invsqrt->getImaginary(),
|
||||
$complex->getImaginary() + $invsqrt->getReal()
|
||||
);
|
||||
$log = ln($adjust);
|
||||
|
||||
return new Complex(
|
||||
$log->getImaginary(),
|
||||
-1 * $log->getReal()
|
||||
);
|
||||
}
|
34
inc/vendor/markbaker/complex/classes/src/functions/acosh.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acosh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic cosine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic cosine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function acosh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal() && ($complex->getReal() > 1)) {
|
||||
return new Complex(\acosh($complex->getReal()));
|
||||
}
|
||||
|
||||
$acosh = acos($complex)
|
||||
->reverse();
|
||||
if ($acosh->getReal() < 0.0) {
|
||||
$acosh = $acosh->invertReal();
|
||||
}
|
||||
|
||||
return $acosh;
|
||||
}
|
25
inc/vendor/markbaker/complex/classes/src/functions/acot.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acot() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse cotangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse cotangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function acot($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return atan(inverse($complex));
|
||||
}
|
25
inc/vendor/markbaker/complex/classes/src/functions/acoth.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acoth() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic cotangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic cotangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function acoth($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return atanh(inverse($complex));
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/acsc.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acsc() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse cosecant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse cosecant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function acsc($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return asin(inverse($complex));
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/acsch.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex acsch() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic cosecant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic cosecant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function acsch($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return asinh(inverse($complex));
|
||||
}
|
28
inc/vendor/markbaker/complex/classes/src/functions/argument.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex argument() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the argument of a complex number.
|
||||
* Also known as the theta of the complex number, i.e. the angle in radians
|
||||
* from the real axis to the representation of the number in polar coordinates.
|
||||
*
|
||||
* This function is a synonym for theta()
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The argument (or theta) value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*
|
||||
* @see theta
|
||||
*/
|
||||
function argument($complex)
|
||||
{
|
||||
return theta($complex);
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/asec.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asec() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse secant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse secant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function asec($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return acos(inverse($complex));
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/asech.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asech() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic secant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic secant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function asech($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return acosh(inverse($complex));
|
||||
}
|
37
inc/vendor/markbaker/complex/classes/src/functions/asin.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asin() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse sine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse sine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function asin($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$square = multiply($complex, $complex);
|
||||
$invsqrt = new Complex(1.0);
|
||||
$invsqrt = subtract($invsqrt, $square);
|
||||
$invsqrt = sqrt($invsqrt);
|
||||
$adjust = new Complex(
|
||||
$invsqrt->getReal() - $complex->getImaginary(),
|
||||
$invsqrt->getImaginary() + $complex->getReal()
|
||||
);
|
||||
$log = ln($adjust);
|
||||
|
||||
return new Complex(
|
||||
$log->getImaginary(),
|
||||
-1 * $log->getReal()
|
||||
);
|
||||
}
|
33
inc/vendor/markbaker/complex/classes/src/functions/asinh.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex asinh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic sine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic sine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function asinh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal() && ($complex->getReal() > 1)) {
|
||||
return new Complex(\asinh($complex->getReal()));
|
||||
}
|
||||
|
||||
$asinh = clone $complex;
|
||||
$asinh = $asinh->reverse()
|
||||
->invertReal();
|
||||
$asinh = asin($asinh);
|
||||
return $asinh->reverse()
|
||||
->invertImaginary();
|
||||
}
|
45
inc/vendor/markbaker/complex/classes/src/functions/atan.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex atan() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
//include_once 'Math/Complex.php';
|
||||
//include_once 'Math/ComplexOp.php';
|
||||
|
||||
/**
|
||||
* Returns the inverse tangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse tangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function atan($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\atan($complex->getReal()));
|
||||
}
|
||||
|
||||
$t1Value = new Complex(-1 * $complex->getImaginary(), $complex->getReal());
|
||||
$uValue = new Complex(1, 0);
|
||||
|
||||
$d1Value = clone $uValue;
|
||||
$d1Value = subtract($d1Value, $t1Value);
|
||||
$d2Value = add($t1Value, $uValue);
|
||||
$uResult = $d1Value->divideBy($d2Value);
|
||||
$uResult = ln($uResult);
|
||||
|
||||
return new Complex(
|
||||
(($uResult->getImaginary() == M_PI) ? -M_PI : $uResult->getImaginary()) * -0.5,
|
||||
$uResult->getReal() * 0.5,
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
38
inc/vendor/markbaker/complex/classes/src/functions/atanh.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex atanh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse hyperbolic tangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse hyperbolic tangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function atanh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
$real = $complex->getReal();
|
||||
if ($real >= -1.0 && $real <= 1.0) {
|
||||
return new Complex(\atanh($real));
|
||||
} else {
|
||||
return new Complex(\atanh(1 / $real), (($real < 0.0) ? M_PI_2 : -1 * M_PI_2));
|
||||
}
|
||||
}
|
||||
|
||||
$iComplex = clone $complex;
|
||||
$iComplex = $iComplex->invertImaginary()
|
||||
->reverse();
|
||||
return atan($iComplex)
|
||||
->invertReal()
|
||||
->reverse();
|
||||
}
|
28
inc/vendor/markbaker/complex/classes/src/functions/conjugate.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex conjugate() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the complex conjugate of a complex number
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The conjugate of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function conjugate($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return new Complex(
|
||||
$complex->getReal(),
|
||||
-1 * $complex->getImaginary(),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
34
inc/vendor/markbaker/complex/classes/src/functions/cos.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cos() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the cosine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The cosine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function cos($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\cos($complex->getReal()));
|
||||
}
|
||||
|
||||
return conjugate(
|
||||
new Complex(
|
||||
\cos($complex->getReal()) * \cosh($complex->getImaginary()),
|
||||
\sin($complex->getReal()) * \sinh($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
)
|
||||
);
|
||||
}
|
32
inc/vendor/markbaker/complex/classes/src/functions/cosh.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cosh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic cosine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic cosine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function cosh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\cosh($complex->getReal()));
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\cosh($complex->getReal()) * \cos($complex->getImaginary()),
|
||||
\sinh($complex->getReal()) * \sin($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/cot.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex cot() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the cotangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The cotangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function cot($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return new Complex(INF);
|
||||
}
|
||||
|
||||
return inverse(tan($complex));
|
||||
}
|
24
inc/vendor/markbaker/complex/classes/src/functions/coth.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex coth() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic cotangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic cotangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function coth($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
return inverse(tanh($complex));
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/csc.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex csc() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the cosecant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The cosecant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function csc($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return inverse(sin($complex));
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/csch.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex csch() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic cosecant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic cosecant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function csch($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
return INF;
|
||||
}
|
||||
|
||||
return inverse(sinh($complex));
|
||||
}
|
34
inc/vendor/markbaker/complex/classes/src/functions/exp.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex exp() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the exponential of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The exponential of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function exp($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (($complex->getReal() == 0.0) && (\abs($complex->getImaginary()) == M_PI)) {
|
||||
return new Complex(-1.0, 0.0);
|
||||
}
|
||||
|
||||
$rho = \exp($complex->getReal());
|
||||
|
||||
return new Complex(
|
||||
$rho * \cos($complex->getImaginary()),
|
||||
$rho * \sin($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/inverse.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex inverse() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the inverse of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The inverse of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function inverse($complex)
|
||||
{
|
||||
$complex = clone Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
throw new \InvalidArgumentException('Division by zero');
|
||||
}
|
||||
|
||||
return $complex->divideInto(1.0);
|
||||
}
|
33
inc/vendor/markbaker/complex/classes/src/functions/ln.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex ln() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the natural logarithm of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The natural logarithm of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If the real and the imaginary parts are both zero
|
||||
*/
|
||||
function ln($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\log(rho($complex)),
|
||||
theta($complex),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
32
inc/vendor/markbaker/complex/classes/src/functions/log10.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex log10() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the common logarithm (base 10) of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The common logarithm (base 10) of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If the real and the imaginary parts are both zero
|
||||
*/
|
||||
function log10($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
throw new \InvalidArgumentException();
|
||||
} elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
return new Complex(\log10($complex->getReal()), 0.0, $complex->getSuffix());
|
||||
}
|
||||
|
||||
return ln($complex)
|
||||
->multiply(\log10(Complex::EULER));
|
||||
}
|
32
inc/vendor/markbaker/complex/classes/src/functions/log2.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex log2() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the base-2 logarithm of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The base-2 logarithm of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If the real and the imaginary parts are both zero
|
||||
*/
|
||||
function log2($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
throw new \InvalidArgumentException();
|
||||
} elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {
|
||||
return new Complex(\log($complex->getReal(), 2), 0.0, $complex->getSuffix());
|
||||
}
|
||||
|
||||
return ln($complex)
|
||||
->multiply(\log(Complex::EULER, 2));
|
||||
}
|
31
inc/vendor/markbaker/complex/classes/src/functions/negative.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex negative() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the negative of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The negative value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*
|
||||
* @see rho
|
||||
*
|
||||
*/
|
||||
function negative($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return new Complex(
|
||||
-1 * $complex->getReal(),
|
||||
-1 * $complex->getImaginary(),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
40
inc/vendor/markbaker/complex/classes/src/functions/pow.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex pow() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns a complex number raised to a power.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @param float|integer $power The power to raise this value to
|
||||
* @return Complex The complex argument raised to the real power.
|
||||
* @throws Exception If the power argument isn't a valid real
|
||||
*/
|
||||
function pow($complex, $power)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if (!is_numeric($power)) {
|
||||
throw new Exception('Power argument must be a real number');
|
||||
}
|
||||
|
||||
if ($complex->getImaginary() == 0.0 && $complex->getReal() >= 0.0) {
|
||||
return new Complex(\pow($complex->getReal(), $power));
|
||||
}
|
||||
|
||||
$rValue = \sqrt(($complex->getReal() * $complex->getReal()) + ($complex->getImaginary() * $complex->getImaginary()));
|
||||
$rPower = \pow($rValue, $power);
|
||||
$theta = $complex->argument() * $power;
|
||||
if ($theta == 0) {
|
||||
return new Complex(1);
|
||||
}
|
||||
|
||||
return new Complex($rPower * \cos($theta), $rPower * \sin($theta), $complex->getSuffix());
|
||||
}
|
28
inc/vendor/markbaker/complex/classes/src/functions/rho.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex rho() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the rho of a complex number.
|
||||
* This is the distance/radius from the centrepoint to the representation of the number in polar coordinates.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The rho value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function rho($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return \sqrt(
|
||||
($complex->getReal() * $complex->getReal()) +
|
||||
($complex->getImaginary() * $complex->getImaginary())
|
||||
);
|
||||
}
|
25
inc/vendor/markbaker/complex/classes/src/functions/sec.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sec() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the secant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The secant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function sec($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return inverse(cos($complex));
|
||||
}
|
25
inc/vendor/markbaker/complex/classes/src/functions/sech.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sech() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic secant of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic secant of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function sech($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
return inverse(cosh($complex));
|
||||
}
|
32
inc/vendor/markbaker/complex/classes/src/functions/sin.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sin() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the sine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The sine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function sin($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\sin($complex->getReal()));
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\sin($complex->getReal()) * \cosh($complex->getImaginary()),
|
||||
\cos($complex->getReal()) * \sinh($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
32
inc/vendor/markbaker/complex/classes/src/functions/sinh.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sinh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic sine of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic sine of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function sinh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\sinh($complex->getReal()));
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\sinh($complex->getReal()) * \cos($complex->getImaginary()),
|
||||
\cosh($complex->getReal()) * \sin($complex->getImaginary()),
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
29
inc/vendor/markbaker/complex/classes/src/functions/sqrt.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex sqrt() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the square root of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The Square root of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function sqrt($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
$theta = theta($complex);
|
||||
$delta1 = \cos($theta / 2);
|
||||
$delta2 = \sin($theta / 2);
|
||||
$rho = \sqrt(rho($complex));
|
||||
|
||||
return new Complex($delta1 * $rho, $delta2 * $rho, $complex->getSuffix());
|
||||
}
|
40
inc/vendor/markbaker/complex/classes/src/functions/tan.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex tan() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the tangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The tangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function tan($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->isReal()) {
|
||||
return new Complex(\tan($complex->getReal()));
|
||||
}
|
||||
|
||||
$real = $complex->getReal();
|
||||
$imaginary = $complex->getImaginary();
|
||||
$divisor = 1 + \pow(\tan($real), 2) * \pow(\tanh($imaginary), 2);
|
||||
if ($divisor == 0.0) {
|
||||
throw new \InvalidArgumentException('Division by zero');
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\pow(sech($imaginary)->getReal(), 2) * \tan($real) / $divisor,
|
||||
\pow(sec($real)->getReal(), 2) * \tanh($imaginary) / $divisor,
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
35
inc/vendor/markbaker/complex/classes/src/functions/tanh.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex tanh() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the hyperbolic tangent of a complex number.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return Complex The hyperbolic tangent of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
* @throws \InvalidArgumentException If function would result in a division by zero
|
||||
*/
|
||||
function tanh($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
$real = $complex->getReal();
|
||||
$imaginary = $complex->getImaginary();
|
||||
$divisor = \cos($imaginary) * \cos($imaginary) + \sinh($real) * \sinh($real);
|
||||
if ($divisor == 0.0) {
|
||||
throw new \InvalidArgumentException('Division by zero');
|
||||
}
|
||||
|
||||
return new Complex(
|
||||
\sinh($real) * \cosh($real) / $divisor,
|
||||
0.5 * \sin(2 * $imaginary) / $divisor,
|
||||
$complex->getSuffix()
|
||||
);
|
||||
}
|
38
inc/vendor/markbaker/complex/classes/src/functions/theta.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex theta() function
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Returns the theta of a complex number.
|
||||
* This is the angle in radians from the real axis to the representation of the number in polar coordinates.
|
||||
*
|
||||
* @param Complex|mixed $complex Complex number or a numeric value.
|
||||
* @return float The theta value of the complex argument.
|
||||
* @throws Exception If argument isn't a valid real or complex number.
|
||||
*/
|
||||
function theta($complex)
|
||||
{
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($complex->getReal() == 0.0) {
|
||||
if ($complex->isReal()) {
|
||||
return 0.0;
|
||||
} elseif ($complex->getImaginary() < 0.0) {
|
||||
return M_PI / -2;
|
||||
}
|
||||
return M_PI / 2;
|
||||
} elseif ($complex->getReal() > 0.0) {
|
||||
return \atan($complex->getImaginary() / $complex->getReal());
|
||||
} elseif ($complex->getImaginary() < 0.0) {
|
||||
return -(M_PI - \atan(\abs($complex->getImaginary()) / \abs($complex->getReal())));
|
||||
}
|
||||
|
||||
return M_PI - \atan($complex->getImaginary() / \abs($complex->getReal()));
|
||||
}
|
46
inc/vendor/markbaker/complex/classes/src/operations/add.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex addition operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Adds two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to add
|
||||
* @return Complex
|
||||
*/
|
||||
function add(...$complexValues)
|
||||
{
|
||||
if (count($complexValues) < 2) {
|
||||
throw new \Exception('This function requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$base = array_shift($complexValues);
|
||||
$result = clone Complex::validateComplexArgument($base);
|
||||
|
||||
foreach ($complexValues as $complex) {
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($result->isComplex() && $complex->isComplex() &&
|
||||
$result->getSuffix() !== $complex->getSuffix()) {
|
||||
throw new Exception('Suffix Mismatch');
|
||||
}
|
||||
|
||||
$real = $result->getReal() + $complex->getReal();
|
||||
$imaginary = $result->getImaginary() + $complex->getImaginary();
|
||||
|
||||
$result = new Complex(
|
||||
$real,
|
||||
$imaginary,
|
||||
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
56
inc/vendor/markbaker/complex/classes/src/operations/divideby.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Divides two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to divide
|
||||
* @return Complex
|
||||
*/
|
||||
function divideby(...$complexValues)
|
||||
{
|
||||
if (count($complexValues) < 2) {
|
||||
throw new \Exception('This function requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$base = array_shift($complexValues);
|
||||
$result = clone Complex::validateComplexArgument($base);
|
||||
|
||||
foreach ($complexValues as $complex) {
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($result->isComplex() && $complex->isComplex() &&
|
||||
$result->getSuffix() !== $complex->getSuffix()) {
|
||||
throw new Exception('Suffix Mismatch');
|
||||
}
|
||||
if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
|
||||
throw new \InvalidArgumentException('Division by zero');
|
||||
}
|
||||
|
||||
$delta1 = ($result->getReal() * $complex->getReal()) +
|
||||
($result->getImaginary() * $complex->getImaginary());
|
||||
$delta2 = ($result->getImaginary() * $complex->getReal()) -
|
||||
($result->getReal() * $complex->getImaginary());
|
||||
$delta3 = ($complex->getReal() * $complex->getReal()) +
|
||||
($complex->getImaginary() * $complex->getImaginary());
|
||||
|
||||
$real = $delta1 / $delta3;
|
||||
$imaginary = $delta2 / $delta3;
|
||||
|
||||
$result = new Complex(
|
||||
$real,
|
||||
$imaginary,
|
||||
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
56
inc/vendor/markbaker/complex/classes/src/operations/divideinto.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex division operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Divides two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to divide
|
||||
* @return Complex
|
||||
*/
|
||||
function divideinto(...$complexValues)
|
||||
{
|
||||
if (count($complexValues) < 2) {
|
||||
throw new \Exception('This function requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$base = array_shift($complexValues);
|
||||
$result = clone Complex::validateComplexArgument($base);
|
||||
|
||||
foreach ($complexValues as $complex) {
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($result->isComplex() && $complex->isComplex() &&
|
||||
$result->getSuffix() !== $complex->getSuffix()) {
|
||||
throw new Exception('Suffix Mismatch');
|
||||
}
|
||||
if ($result->getReal() == 0.0 && $result->getImaginary() == 0.0) {
|
||||
throw new \InvalidArgumentException('Division by zero');
|
||||
}
|
||||
|
||||
$delta1 = ($complex->getReal() * $result->getReal()) +
|
||||
($complex->getImaginary() * $result->getImaginary());
|
||||
$delta2 = ($complex->getImaginary() * $result->getReal()) -
|
||||
($complex->getReal() * $result->getImaginary());
|
||||
$delta3 = ($result->getReal() * $result->getReal()) +
|
||||
($result->getImaginary() * $result->getImaginary());
|
||||
|
||||
$real = $delta1 / $delta3;
|
||||
$imaginary = $delta2 / $delta3;
|
||||
|
||||
$result = new Complex(
|
||||
$real,
|
||||
$imaginary,
|
||||
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
48
inc/vendor/markbaker/complex/classes/src/operations/multiply.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex multiplication operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Multiplies two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to multiply
|
||||
* @return Complex
|
||||
*/
|
||||
function multiply(...$complexValues)
|
||||
{
|
||||
if (count($complexValues) < 2) {
|
||||
throw new \Exception('This function requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$base = array_shift($complexValues);
|
||||
$result = clone Complex::validateComplexArgument($base);
|
||||
|
||||
foreach ($complexValues as $complex) {
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($result->isComplex() && $complex->isComplex() &&
|
||||
$result->getSuffix() !== $complex->getSuffix()) {
|
||||
throw new Exception('Suffix Mismatch');
|
||||
}
|
||||
|
||||
$real = ($result->getReal() * $complex->getReal()) -
|
||||
($result->getImaginary() * $complex->getImaginary());
|
||||
$imaginary = ($result->getReal() * $complex->getImaginary()) +
|
||||
($result->getImaginary() * $complex->getReal());
|
||||
|
||||
$result = new Complex(
|
||||
$real,
|
||||
$imaginary,
|
||||
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
46
inc/vendor/markbaker/complex/classes/src/operations/subtract.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Function code for the complex subtraction operation
|
||||
*
|
||||
* @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
|
||||
* @license https://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
namespace Complex;
|
||||
|
||||
/**
|
||||
* Subtracts two or more complex numbers
|
||||
*
|
||||
* @param array of string|integer|float|Complex $complexValues The numbers to subtract
|
||||
* @return Complex
|
||||
*/
|
||||
function subtract(...$complexValues)
|
||||
{
|
||||
if (count($complexValues) < 2) {
|
||||
throw new \Exception('This function requires at least 2 arguments');
|
||||
}
|
||||
|
||||
$base = array_shift($complexValues);
|
||||
$result = clone Complex::validateComplexArgument($base);
|
||||
|
||||
foreach ($complexValues as $complex) {
|
||||
$complex = Complex::validateComplexArgument($complex);
|
||||
|
||||
if ($result->isComplex() && $complex->isComplex() &&
|
||||
$result->getSuffix() !== $complex->getSuffix()) {
|
||||
throw new Exception('Suffix Mismatch');
|
||||
}
|
||||
|
||||
$real = $result->getReal() - $complex->getReal();
|
||||
$imaginary = $result->getImaginary() - $complex->getImaginary();
|
||||
|
||||
$result = new Complex(
|
||||
$real,
|
||||
$imaginary,
|
||||
($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix())
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
77
inc/vendor/markbaker/complex/composer.json
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"type": "library",
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"keywords": ["complex", "mathematics"],
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6.0|^7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.0",
|
||||
"phpdocumentor/phpdocumentor":"2.*",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"sebastian/phpcpd": "2.*",
|
||||
"phploc/phploc": "2.*",
|
||||
"squizlabs/php_codesniffer": "^3.3.0",
|
||||
"phpcompatibility/php-compatibility": "^8.0",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
},
|
||||
"files": [
|
||||
"classes/src/functions/abs.php",
|
||||
"classes/src/functions/acos.php",
|
||||
"classes/src/functions/acosh.php",
|
||||
"classes/src/functions/acot.php",
|
||||
"classes/src/functions/acoth.php",
|
||||
"classes/src/functions/acsc.php",
|
||||
"classes/src/functions/acsch.php",
|
||||
"classes/src/functions/argument.php",
|
||||
"classes/src/functions/asec.php",
|
||||
"classes/src/functions/asech.php",
|
||||
"classes/src/functions/asin.php",
|
||||
"classes/src/functions/asinh.php",
|
||||
"classes/src/functions/atan.php",
|
||||
"classes/src/functions/atanh.php",
|
||||
"classes/src/functions/conjugate.php",
|
||||
"classes/src/functions/cos.php",
|
||||
"classes/src/functions/cosh.php",
|
||||
"classes/src/functions/cot.php",
|
||||
"classes/src/functions/coth.php",
|
||||
"classes/src/functions/csc.php",
|
||||
"classes/src/functions/csch.php",
|
||||
"classes/src/functions/exp.php",
|
||||
"classes/src/functions/inverse.php",
|
||||
"classes/src/functions/ln.php",
|
||||
"classes/src/functions/log2.php",
|
||||
"classes/src/functions/log10.php",
|
||||
"classes/src/functions/negative.php",
|
||||
"classes/src/functions/pow.php",
|
||||
"classes/src/functions/rho.php",
|
||||
"classes/src/functions/sec.php",
|
||||
"classes/src/functions/sech.php",
|
||||
"classes/src/functions/sin.php",
|
||||
"classes/src/functions/sinh.php",
|
||||
"classes/src/functions/sqrt.php",
|
||||
"classes/src/functions/tan.php",
|
||||
"classes/src/functions/tanh.php",
|
||||
"classes/src/functions/theta.php",
|
||||
"classes/src/operations/add.php",
|
||||
"classes/src/operations/subtract.php",
|
||||
"classes/src/operations/multiply.php",
|
||||
"classes/src/operations/divideby.php",
|
||||
"classes/src/operations/divideinto.php"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
154
inc/vendor/markbaker/complex/examples/complexTest.php
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
use Complex\Complex as Complex;
|
||||
|
||||
include('../classes/Bootstrap.php');
|
||||
|
||||
echo 'Create', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123, 456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(array(123,456,'j'));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex('1.23e-4--2.34e-5i');
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
|
||||
echo PHP_EOL, 'Add', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
$x->add(456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456);
|
||||
$x->add(789.012);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->add(new Complex(-987.654, -32.1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->add(-987.654);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->add(new Complex(0, 1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->add(new Complex(0, -1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
|
||||
echo PHP_EOL, 'Subtract', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
$x->subtract(456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456);
|
||||
$x->subtract(789.012);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->subtract(new Complex(-987.654, -32.1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->subtract(-987.654);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->subtract(new Complex(0, 1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->subtract(new Complex(0, -1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
|
||||
echo PHP_EOL, 'Multiply', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
$x->multiply(456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456);
|
||||
$x->multiply(789.012);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->multiply(new Complex(-987.654, -32.1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->multiply(-987.654);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->multiply(new Complex(0, 1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->multiply(new Complex(0, -1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
|
||||
echo PHP_EOL, 'Divide By', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
$x->divideBy(456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456);
|
||||
$x->divideBy(789.012);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->divideBy(new Complex(-987.654, -32.1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->divideBy(-987.654);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->divideBy(new Complex(0, 1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->divideBy(new Complex(0, -1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
|
||||
echo PHP_EOL, 'Divide Into', PHP_EOL;
|
||||
|
||||
$x = new Complex(123);
|
||||
$x->divideInto(456);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456);
|
||||
$x->divideInto(789.012);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->divideInto(new Complex(-987.654, -32.1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(123.456, 78.90);
|
||||
$x->divideInto(-987.654);
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->divideInto(new Complex(0, 1));
|
||||
echo $x, PHP_EOL;
|
||||
|
||||
$x = new Complex(-987.654, -32.1);
|
||||
$x->divideInto(new Complex(0, -1));
|
||||
echo $x, PHP_EOL;
|
52
inc/vendor/markbaker/complex/examples/testFunctions.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Complex;
|
||||
|
||||
include('../classes/Bootstrap.php');
|
||||
|
||||
echo 'Function Examples', PHP_EOL;
|
||||
|
||||
$functions = array(
|
||||
'abs',
|
||||
'acos',
|
||||
'acosh',
|
||||
'acsc',
|
||||
'acsch',
|
||||
'argument',
|
||||
'asec',
|
||||
'asech',
|
||||
'asin',
|
||||
'asinh',
|
||||
'conjugate',
|
||||
'cos',
|
||||
'cosh',
|
||||
'csc',
|
||||
'csch',
|
||||
'exp',
|
||||
'inverse',
|
||||
'ln',
|
||||
'log2',
|
||||
'log10',
|
||||
'rho',
|
||||
'sec',
|
||||
'sech',
|
||||
'sin',
|
||||
'sinh',
|
||||
'sqrt',
|
||||
'theta'
|
||||
);
|
||||
|
||||
for ($real = -3.5; $real <= 3.5; $real += 0.5) {
|
||||
for ($imaginary = -3.5; $imaginary <= 3.5; $imaginary += 0.5) {
|
||||
foreach ($functions as $function) {
|
||||
$complexFunction = __NAMESPACE__ . '\\' . $function;
|
||||
$complex = new Complex($real, $imaginary);
|
||||
try {
|
||||
echo $function, '(', $complex, ') = ', $complexFunction($complex), PHP_EOL;
|
||||
} catch (\Exception $e) {
|
||||
echo $function, '(', $complex, ') ERROR: ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
}
|
||||
echo PHP_EOL;
|
||||
}
|
||||
}
|
34
inc/vendor/markbaker/complex/examples/testOperations.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Complex\Complex as Complex;
|
||||
|
||||
include('../classes/Bootstrap.php');
|
||||
|
||||
$values = [
|
||||
new Complex(123),
|
||||
new Complex(456, 123),
|
||||
new Complex(0.0, 456),
|
||||
];
|
||||
|
||||
foreach ($values as $value) {
|
||||
echo $value, PHP_EOL;
|
||||
}
|
||||
|
||||
echo 'Addition', PHP_EOL;
|
||||
|
||||
$result = \Complex\add(...$values);
|
||||
echo '=> ', $result, PHP_EOL;
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
echo 'Subtraction', PHP_EOL;
|
||||
|
||||
$result = \Complex\subtract(...$values);
|
||||
echo '=> ', $result, PHP_EOL;
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
echo 'Multiplication', PHP_EOL;
|
||||
|
||||
$result = \Complex\multiply(...$values);
|
||||
echo '=> ', $result, PHP_EOL;
|
25
inc/vendor/markbaker/complex/license.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright © `2017` `Mark Baker`
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the “Software”), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
5
inc/vendor/pacificsec/cpe/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/.settings/
|
||||
/.buildpath
|
||||
/.project
|
||||
/vendor/
|
||||
/composer.lock
|
42
inc/vendor/pacificsec/cpe/README.md
vendored
@ -22,3 +22,45 @@ Features
|
||||
- CPE rich comparison.
|
||||
- CPE Language parsing and evaluation.
|
||||
- MIT Licensed.
|
||||
|
||||
Getting Started
|
||||
--------
|
||||
- Clone repository
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/pacificsec/cpe.git
|
||||
$ cd cpe
|
||||
```
|
||||
- Create a new PHP file to run tests
|
||||
|
||||
```php
|
||||
<?php
|
||||
require('autoload.php');
|
||||
|
||||
use PacificSec\CPE\Matching\CPENameMatcher;
|
||||
use PacificSec\CPE\Naming\CPENameUnbinder;
|
||||
use PacificSec\CPE\Naming\CPENameBinder;
|
||||
|
||||
CPENameMatcher::test();
|
||||
CPENameUnbinder::test();
|
||||
CPENameBinder::test();
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
require('autoload.php');
|
||||
|
||||
use PacificSec\CPE\Naming\CPENameUnbinder;
|
||||
|
||||
$cpenu = new CPENameUnbinder();
|
||||
$wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer%01%01%01%01:?:beta");
|
||||
var_dump($wfn);
|
||||
$wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%2a:sp%3f");
|
||||
var_dump($wfn);
|
||||
$wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%02:sp%01");
|
||||
var_dump($wfn);
|
||||
$wfn = $cpenu->unbindURI("cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~");
|
||||
var_dump($wfn);
|
||||
$wfn = $cpenu->unbindFS("cpe:2.3:a:micr\\?osoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*");
|
||||
var_dump($wfn);
|
||||
```
|
26
inc/vendor/pacificsec/cpe/composer.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name" : "pacificsec/cpe",
|
||||
"type" : "library",
|
||||
"description" : "CPE: Common Platform Enumeration for PHP",
|
||||
"keywords" : [
|
||||
"cpe",
|
||||
"cve",
|
||||
"security",
|
||||
"pacificsec"
|
||||
],
|
||||
"homepage" : "https://github.com/pacificsec/cpe",
|
||||
"license" : "MIT",
|
||||
"authors" : [{
|
||||
"name" : "Antonio Franco",
|
||||
"email" : "antonio.franco@pacificsec.com"
|
||||
}
|
||||
],
|
||||
"require" : {
|
||||
"php" : ">=5.3.0"
|
||||
},
|
||||
"autoload" : {
|
||||
"psr-4" : {
|
||||
"PacificSec\\CPE\\" : "src"
|
||||
}
|
||||
}
|
||||
}
|
44
inc/vendor/pacificsec/cpe/src/Common/LogicalValue.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace PacificSec\CPE\Common;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* This class represents a Logical Value. It is based on Java version
|
||||
* implemented by JKRAUNELIS <jkraunelis@mitre.org>.
|
||||
*
|
||||
* @see <a href="http://cpe.mitre.org">cpe.mitre.org</a> for more information.
|
||||
* @author Antonio Franco
|
||||
* @email antonio.franco@pacificsec.com
|
||||
*/
|
||||
class LogicalValue {
|
||||
|
||||
private $any = false;
|
||||
private $na = false;
|
||||
|
||||
// Object must be constructed with the string "ANY" or "NA".
|
||||
public function __construct($type) {
|
||||
if ($type == "ANY") {
|
||||
$this->any = true;
|
||||
} else if ($type == "NA") {
|
||||
$this->na = true;
|
||||
} else {
|
||||
throw new Exception("LogicalValue must be ANY or NA");
|
||||
}
|
||||
}
|
||||
|
||||
public function isANY(){
|
||||
return $this->any;
|
||||
}
|
||||
|
||||
public function isNA(){
|
||||
return $this->na;
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
if ($this->any){
|
||||
return "ANY";
|
||||
}
|
||||
return "NA";
|
||||
}
|
||||
}
|
166
inc/vendor/pacificsec/cpe/src/Common/Utilities.php
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
namespace PacificSec\CPE\Common;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* A collection of utility functions for use with the matching and
|
||||
* naming namespaces. It is based on Java version implemented by
|
||||
* Joshua Kraunelis <jkraunelis@mitre.org>.
|
||||
*
|
||||
* @see <a href="http://cpe.mitre.org">cpe.mitre.org</a> for more information.
|
||||
* @author Antonio Franco
|
||||
* @email antonio.franco@pacificsec.com
|
||||
*/
|
||||
class Utilities {
|
||||
|
||||
/**
|
||||
* Searches string for special characters * and ?
|
||||
* @param string $string to be searched
|
||||
* @return bool true if string contains wildcard, false otherwise
|
||||
*/
|
||||
public static function containsWildcards($string) {
|
||||
if (strpos($string, "*") !== false || strpos($string, "?") !== false) {
|
||||
if (!(strpos($string, "\\") !== false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given number is even or not
|
||||
* @param int $num number to check
|
||||
* @return bool true if number is even, false if not
|
||||
*/
|
||||
public static function isEvenNumber($num) {
|
||||
return (is_int($num) && $num % 2 == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of escape characters in the string beginning and ending
|
||||
* at the given indices
|
||||
* @param string $str string to search
|
||||
* @param int $start beginning index
|
||||
* @param int $end ending index
|
||||
* @return number of escape characters in string
|
||||
* @todo fix the use of $str. The Java version is also not using this variable.
|
||||
*/
|
||||
public static function countEscapeCharacters($str, $start, $end) {
|
||||
$result = 0;
|
||||
$active = false;
|
||||
$i = 0;
|
||||
while ($i < $end) {
|
||||
if ($active && ($i >= $start)) {
|
||||
$result = $result + 1;
|
||||
}
|
||||
$i = $i + 1;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a string for the first unescaped colon and returns the index of
|
||||
* that colon
|
||||
* @param string $str string to search
|
||||
* @return int index of first unescaped colon, or 0 if not found
|
||||
*/
|
||||
public static function getUnescapedColonIndex($str) {
|
||||
$found = false;
|
||||
$colon_idx = 0;
|
||||
$start_idx = 0;
|
||||
// Find the first non-escaped colon.
|
||||
while (!$found) {
|
||||
$colon_idx = strpos($str, ":", $start_idx + 1);
|
||||
// If no colon is found, return 0.
|
||||
if ($colon_idx === false) {
|
||||
return 0;
|
||||
}
|
||||
// Peek at character before colon.
|
||||
if (substr($str, $colon_idx-1, 1) == "\\") {
|
||||
// If colon is escaped, keep looking.
|
||||
$start_idx = $colon_idx;
|
||||
} else {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
return $colon_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the string contains only
|
||||
* alphanumeric characters or the underscore character,
|
||||
* false otherwise.
|
||||
* @param string $c the string in question
|
||||
* @return bool true if $c is alphanumeric or underscore, false if not
|
||||
*/
|
||||
public static function isAlphanum($c) {
|
||||
return (preg_match("/^[a-zA-Z0-9\_]+$/", $c) ? true : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is not part of the reference implementation pseudo code
|
||||
* found in the CPE 2.3 specification. It enforces two rules in the
|
||||
* specification:
|
||||
* URI must start with the characters "cpe:/"
|
||||
* A URI may not contain more than 7 components
|
||||
* If either rule is violated, a Exception is thrown.
|
||||
* @param $in string with URI to be validated
|
||||
*/
|
||||
public static function validateURI($in) {
|
||||
// make sure uri starts with cpe:/
|
||||
if (strpos(strtolower($in), "cpe:/") !== 0) {
|
||||
throw new Exception("Error: URI must start with 'cpe:/'. Given: " . $in, 0);
|
||||
}
|
||||
// make sure uri doesn't contain more than 7 colons
|
||||
$count = sizeof(explode(":", $in));
|
||||
if ($count > 8) {
|
||||
throw new Exception("Error parsing URI. Found " . ($count - 8) . " extra components in: " . $in, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is not part of the reference implementation pseudo code
|
||||
* found in the CPE 2.3 specification. It enforces three rules found in the
|
||||
* specification:
|
||||
* Formatted string must start with the characters "cpe:2.3:"
|
||||
* A formatted string must contain 11 components
|
||||
* A formatted string must not contain empty components
|
||||
* If any rule is violated, a ParseException is thrown.
|
||||
* @param $in string with FS to be validated
|
||||
*/
|
||||
public static function validateFS($in) {
|
||||
if (strpos(strtolower($in), "cpe:2.3:") !== 0) {
|
||||
throw new Exception("Error: Formatted String must start with \"cpe:2.3\". Given: " . $in, 0);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
for ($i = 0; $i != strlen($in); $i++){
|
||||
if (substr($in, $i, 1) == ":"){
|
||||
if (substr($in, $i - 1, 1) != "\\"){
|
||||
$count++;
|
||||
}
|
||||
if (($i+1) < strlen($in) && substr($in, $i+1, 1) == ":"){
|
||||
throw new Exception("Error parsing formatted string. Found empty component", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($count > 12){
|
||||
$extra = $count - 12;
|
||||
$s = "Error parsing formatted string. Found " . $extra . " extra component";
|
||||
if ($extra > 1){
|
||||
$s = $s . "s";
|
||||
}
|
||||
$s = $s . " in: " . $in;
|
||||
throw new Exception($s, 0);
|
||||
}
|
||||
if ($count < 12){
|
||||
$missing = 12 - $count;
|
||||
$s = "Error parsing formatted string. Missing " . $missing . " component";
|
||||
if ($missing > 1){
|
||||
$s = $s . "s";
|
||||
}
|
||||
throw new Exception($s, 0);
|
||||
}
|
||||
}
|
||||
}
|
210
inc/vendor/pacificsec/cpe/src/Common/WellFormedName.php
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
<?php
|
||||
namespace PacificSec\CPE\Common;
|
||||
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* The WellFormedName class represents a Well Formed Name, as defined
|
||||
* in the CPE Specification version 2.3. It is based on Java version
|
||||
* implemented by jkraunelis <jkraunelis@mitre.org>.
|
||||
*
|
||||
* @see <a href="http://cpe.mitre.org">cpe.mitre.org</a> for details.
|
||||
* @author Antonio Franco
|
||||
* @email antonio.franco@pacificsec.com
|
||||
*/
|
||||
class WellFormedName {
|
||||
|
||||
// Underlying wfn representation.
|
||||
private $wfn = null;
|
||||
// All permissible WFN attributes as defined by specification.
|
||||
private $attributes = array("part", "vendor", "product", "version",
|
||||
"update", "edition", "language", "sw_edition", "target_sw",
|
||||
"target_hw", "other");
|
||||
|
||||
/**
|
||||
* Constructs a new WellFormedName object, setting each component to the
|
||||
* given parameter value. If a parameter is null, the component is set to
|
||||
* the default value "ANY".
|
||||
* @param $part string representing the part component
|
||||
* @param $vendor string representing the vendor component
|
||||
* @param $product string representing the product component
|
||||
* @param $version string representing the version component
|
||||
* @param $update string representing the update component
|
||||
* @param $edition string representing the edition component
|
||||
* @param $language string representing the language component
|
||||
* @param $sw_edition string representing the sw_edition component
|
||||
* @param $target_sw string representing the target_sw component
|
||||
* @param $target_hw string representing the target_hw component
|
||||
* @param $other string representing the other component
|
||||
*/
|
||||
public function __construct($part = null, $vendor = null, $product = null, $version = null,
|
||||
$update = null, $edition = null, $language = null, $sw_edition = null, $target_sw = null,
|
||||
$target_hw = null, $other = null) {
|
||||
|
||||
$this->wfn = array();
|
||||
|
||||
// Constructs a new WellFormedName object, with all components set to the default value "ANY".
|
||||
if ($part === null && $vendor === null && $product === null && $version === null &&
|
||||
$update === null && $edition === null && $language === null && $sw_edition === null && $target_sw === null &&
|
||||
$target_hw === null && $other === null){
|
||||
foreach ($this->attributes as $a){
|
||||
if ($a != "part"){
|
||||
$this->set($a, new LogicalValue("ANY"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->set("part", $part);
|
||||
$this->set("vendor", $vendor);
|
||||
$this->set("product", $product);
|
||||
$this->set("version", $version);
|
||||
$this->set("update", $update);
|
||||
$this->set("edition", $edition);
|
||||
$this->set("language", $language);
|
||||
$this->set("sw_edition", $sw_edition);
|
||||
$this->set("target_sw", $target_sw);
|
||||
$this->set("target_hw", $target_hw);
|
||||
$this->set("other", $other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute string representing the component value to get
|
||||
* @return string the string value of the given component, or default value "ANY"
|
||||
* if the component does not exist
|
||||
*/
|
||||
public function get($attribute){
|
||||
if (array_key_exists($attribute, $this->wfn))
|
||||
return $this->wfn[$attribute];
|
||||
else
|
||||
return new LogicalValue("ANY");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given attribute to value, if the attribute is in the list of
|
||||
* permissible components
|
||||
* @param $attribute string representing the component to set
|
||||
* @param $value object or string representing the value of the given component
|
||||
*/
|
||||
public final function set($attribute, $value){
|
||||
// Iterate over permissible attributes.
|
||||
foreach ($this->attributes as $a){
|
||||
// If the argument is a valid attribute, set that attribute's value.
|
||||
if ($attribute == $a) {
|
||||
// check to see if we're setting a LogicalValue ANY or NA
|
||||
if ($value instanceof LogicalValue){
|
||||
// don't allow logical values in part component
|
||||
if ($attribute == "part"){
|
||||
var_dump($value); echo "<br>\n";
|
||||
var_dump($a); echo "<br>\n";
|
||||
var_dump($attribute); echo "<br>\n";
|
||||
throw new Exception("Error! part component cannot be a logical value");
|
||||
}
|
||||
// put the Object in the ht and break
|
||||
$this->wfn[$attribute] = $value;
|
||||
break;
|
||||
}
|
||||
if ($value == null || $value == ""){
|
||||
// if value is null or blank, set attribute to default logical ANY
|
||||
$this->wfn[$attribute] = new LogicalValue("ANY");
|
||||
break;
|
||||
}
|
||||
$svalue = $value;
|
||||
// Reg exs
|
||||
// check for printable characters - no control characters
|
||||
if (!preg_match("/^[[:print:]]*$/", $svalue)){
|
||||
throw new Exception("Error! encountered non printable character in: " . $svalue, 0);
|
||||
}
|
||||
// svalue has whitespace
|
||||
if (preg_match("/^.*\\s+.*$/", $svalue)){
|
||||
throw new Exception("Error! component cannot contain whitespace: " . $svalue, 0);
|
||||
}
|
||||
// svalue has more than one unquoted star
|
||||
if (preg_match("/^\\*{2,}.*$/", $svalue) || preg_match("/^.*\\*{2,}$/", $svalue)){
|
||||
throw new Exception("Error! component cannot contain more than one * in sequence: " . $svalue, 0);
|
||||
}
|
||||
// svalue has unquoted punctuation embedded
|
||||
if (preg_match("/^.*(?<!\\\\)[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\+\\,\\.\\/\\:\\;\\<\\=\\>\\@\\[\\]\\^\\`\\{\\|\\}\\~\\-].*$/", $svalue)) {
|
||||
throw new Exception("Error! component cannot contain unquoted punctuation: " . $svalue, 0);
|
||||
}
|
||||
// svalue has an unquoted *
|
||||
if (preg_match("/^.+(?<!\\\\)[\\*].+$/", $svalue)) {
|
||||
throw new Exception("Error! component cannot contain embedded *: " . $svalue, 0);
|
||||
}
|
||||
// svalue has embedded unquoted ?
|
||||
// this will catch a single unquoted ?, so make sure we deal with that
|
||||
if (strpos($svalue, "?") !== false) {
|
||||
if ($svalue == "?") {
|
||||
// single ? is valid
|
||||
$this->wfn[$attribute] = $svalue;
|
||||
break;
|
||||
}
|
||||
// remove leading and trailing ?s
|
||||
$v = $svalue;
|
||||
while (strpos($v, "?") === 0) {
|
||||
// remove all leading ?'s
|
||||
$v = substr($v, 1);
|
||||
}
|
||||
$v = strrev($v);
|
||||
while (strpos($v, "?") === 0) {
|
||||
// remove all trailing ?'s (string has been reversed)
|
||||
$v = substr($v, 1);
|
||||
}
|
||||
// back to normal
|
||||
$v = strrev($v);
|
||||
// after leading and trailing ?s are removed, check if value
|
||||
// contains unquoted ?s
|
||||
if (preg_match("/^.+(?<!\\\\)[\\?].+$/", $v)) {
|
||||
throw new Exception("Error! component cannot contain embedded ?: " . $svalue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// single asterisk is not allowed
|
||||
if ($svalue == "*") {
|
||||
throw new Exception("Error! component cannot be a single *: " . $svalue, 0);
|
||||
}
|
||||
// quoted hyphen not allowed by itself
|
||||
if ($svalue == "-") {
|
||||
throw new Exception("Error! component cannot be quoted hyphen: " . $svalue, 0);
|
||||
}
|
||||
// part must be a, o, or h
|
||||
if ($attribute == "part") {
|
||||
if ($svalue != "a" && $svalue != "o" && $svalue != "h") {
|
||||
throw new Exception("Error! part component must be one of the following: 'a', 'o', 'h': " . $svalue, 0);
|
||||
}
|
||||
}
|
||||
// should be good to go
|
||||
$this->wfn[$attribute] = $svalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string representation of the WellFormedName
|
||||
*/
|
||||
public function __toString() {
|
||||
$str = "wfn:[";
|
||||
foreach ($this->attributes as $attr) {
|
||||
$str = $str . $attr;
|
||||
$str = $str . "=";
|
||||
|
||||
$o = $this->wfn[$attr];
|
||||
if ($o instanceof LogicalValue) {
|
||||
$str = $str . $o;
|
||||
$str = $str . ", ";
|
||||
} else {
|
||||
$str = $str . "\"";
|
||||
$str = $str . $o;
|
||||
$str = $str . "\", ";
|
||||
}
|
||||
}
|
||||
$str = substr($str, 0, strlen($str)-1);
|
||||
$str = substr($str, 0, strlen($str)-1);
|
||||
$str = $str . "]";
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
287
inc/vendor/pacificsec/cpe/src/Matching/CPENameMatcher.php
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
namespace PacificSec\CPE\Matching;
|
||||
|
||||
use PacificSec\CPE\Common\WellFormedName;
|
||||
use PacificSec\CPE\Common\Utilities;
|
||||
use PacificSec\CPE\Common\LogicalValue;
|
||||
use PacificSec\CPE\Naming\CPENameBinder;
|
||||
use PacificSec\CPE\Naming\CPENameUnbinder;
|
||||
|
||||
/**
|
||||
* The CPENameMatcher is an implementation of the CPE Matching algorithm,
|
||||
* as specified in the CPE Matching Standard version 2.3. It is based on
|
||||
* Java version implemented by Joshua Kraunelis <jkraunelis@mitre.org>.
|
||||
*
|
||||
* @see <a href="http://cpe.mitre.org">cpe.mitre.org</a> for more information.
|
||||
* @author Antonio Franco
|
||||
* @email antonio.franco@pacificsec.com
|
||||
*/
|
||||
class CPENameMatcher {
|
||||
|
||||
/**
|
||||
* Tests two Well Formed Names for disjointness.
|
||||
* @param $source WellFormedName Source WFN
|
||||
* @param $target WellFormedName Target WFN
|
||||
* @return true if the names are disjoint, false otherwise
|
||||
*/
|
||||
public function isDisjoint(WellFormedName $source, WellFormedName $target) {
|
||||
// if any pairwise comparison is disjoint, the names are disjoint.
|
||||
$resultList = $this->compareWFNs($source, $target);
|
||||
foreach ($resultList as $result){
|
||||
if ($result == Relation::DISJOINT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests two Well Formed Names for equality.
|
||||
* @param $source WellFormedName Source WFN
|
||||
* @param $target WellFormedName Target WFN
|
||||
* @return true if the names are equal, false otherwise
|
||||
*/
|
||||
public function isEqual(WellFormedName $source, WellFormedName $target) {
|
||||
// if every pairwise comparison is equal, the names are equal.
|
||||
$resultList = $this->compareWFNs($source, $target);
|
||||
foreach ($resultList as $result){
|
||||
if ($result != Relation::EQUAL){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the target Well Formed Name is a subset of the source Well Formed
|
||||
* Name.
|
||||
* @param $source WellFormedName Source WFN
|
||||
* @param $target WellFormedName Target WFN
|
||||
* @return true if the target is a subset of the source, false otherwise
|
||||
*/
|
||||
public function isSubset(WellFormedName $source, WellFormedName $target) {
|
||||
// if any comparison is anything other than subset or equal, then target is
|
||||
// not a subset of source.
|
||||
$resultList = $this->compareWFNs($source, $target);
|
||||
foreach ($resultList as $result){
|
||||
if ($result != Relation::SUBSET && $result != Relation::EQUAL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the target Well Formed name is a superset of the source Well Formed
|
||||
* Name.
|
||||
* @param $source WellFormedName Source WFN
|
||||
* @param $target WellFormedName Target WFN
|
||||
* @return true if the target is a superset of the source, false otherwise
|
||||
*/
|
||||
public function isSuperset(WellFormedName $source, WellFormedName $target) {
|
||||
// if any comparison is anything other than superset or equal, then target is not
|
||||
// a superset of source.
|
||||
$resultList = $this->compareWFNs($source, $target);
|
||||
foreach ($resultList as $result){
|
||||
if ($result != Relation::SUPERSET && $result != Relation::EQUAL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares each attribute value pair in two Well Formed Names.
|
||||
* @param $source WellFormedName Source WFN
|
||||
* @param $target WellFormedName Target WFN
|
||||
* @return array A array mapping attribute string to attribute value Relation
|
||||
*/
|
||||
public function compareWFNs(WellFormedName $source, WellFormedName $target) {
|
||||
$result = array();
|
||||
$result["part"] = $this->compare($source->get("part"), $target->get("part"));
|
||||
$result["vendor"] = $this->compare($source->get("vendor"), $target->get("vendor"));
|
||||
$result["product"] = $this->compare($source->get("product"), $target->get("product"));
|
||||
$result["version"] = $this->compare($source->get("version"), $target->get("version"));
|
||||
$result["update"] = $this->compare($source->get("update"), $target->get("update"));
|
||||
$result["edition"] = $this->compare($source->get("edition"), $target->get("edition"));
|
||||
$result["language"] = $this->compare($source->get("language"), $target->get("language"));
|
||||
$result["sw_edition"] = $this->compare($source->get("sw_edition"), $target->get("sw_edition"));
|
||||
$result["target_sw"] = $this->compare($source->get("target_sw"), $target->get("target_sw"));
|
||||
$result["target_hw"] = $this->compare($source->get("target_hw"), $target->get("target_hw"));
|
||||
$result["other"] = $this->compare($source->get("other"), $target->get("other"));
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares an attribute value pair.
|
||||
* @param string $source Source attribute value.
|
||||
* @param string $target Target attribute value.
|
||||
* @return int The relation between the two attribute values.
|
||||
*/
|
||||
private function compare($source, $target) {
|
||||
// matching is case insensitive, convert strings to lowercase.
|
||||
if ($this->isString($source)) {
|
||||
$source = strtolower($source);
|
||||
}
|
||||
if ($this->isString($target)) {
|
||||
$target = strtolower($target);
|
||||
}
|
||||
|
||||
// Unquoted wildcard characters yield an undefined result.
|
||||
if ($this->isString($target) && Utilities::containsWildcards($target)) {
|
||||
return Relation::UNDEFINED;
|
||||
}
|
||||
// If source and target values are equal, then result is equal.
|
||||
if ($source == $target) {
|
||||
return Relation::EQUAL;
|
||||
}
|
||||
|
||||
// Check to see if source or target are Logical Values.
|
||||
$lvSource = null;
|
||||
$lvTarget = null;
|
||||
if ($source instanceof LogicalValue) {
|
||||
$lvSource = $source;
|
||||
}
|
||||
if ($target instanceof LogicalValue) {
|
||||
$lvTarget = $target;
|
||||
}
|
||||
if ($lvSource != null && $lvTarget != null) {
|
||||
// If Logical Values are equal, result is equal.
|
||||
if ($lvSource->isANY() == $lvTarget->isANY() || $lvSource->isNA() == $lvTarget->isNA()) {
|
||||
return Relation::EQUAL;
|
||||
}
|
||||
}
|
||||
// If source value is ANY, result is a superset.
|
||||
if ($lvSource != null) {
|
||||
if ($lvSource->isANY()) {
|
||||
return Relation::SUPERSET;
|
||||
}
|
||||
}
|
||||
// If target value is ANY, result is a subset.
|
||||
if ($lvTarget != null) {
|
||||
if ($lvTarget->isANY()) {
|
||||
return Relation::SUBSET;
|
||||
}
|
||||
}
|
||||
// If source or target is NA, result is disjoint.
|
||||
if ($lvSource != null) {
|
||||
if ($lvSource->isNA()) {
|
||||
return Relation::DISJOINT;
|
||||
}
|
||||
}
|
||||
if ($lvTarget != null) {
|
||||
if ($lvTarget->isNA()) {
|
||||
return Relation::DISJOINT;
|
||||
}
|
||||
}
|
||||
// only Strings will get to this point, not LogicalValues
|
||||
return $this->compareStrings($source, $target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares a source string to a target string, and addresses the condition
|
||||
* in which the source string includes unquoted special characters. It
|
||||
* performs a simple regular expression match, with the assumption that
|
||||
* (as required) unquoted special characters appear only at the beginning
|
||||
* and/or the end of the source string. It also properly differentiates
|
||||
* between unquoted and quoted special characters.
|
||||
*
|
||||
* @param $source string Source attribute value.
|
||||
* @param $target string Target attribute value.
|
||||
* @return Relation between source and target Strings.
|
||||
*/
|
||||
private function compareStrings($source, $target) {
|
||||
$start = 0;
|
||||
$end = strlen($source);
|
||||
$begins = 0;
|
||||
$ends = 0;
|
||||
$index = 0; $leftover = 0; $escapes = 0;
|
||||
|
||||
if (substr($source, 0, 1) == "*") {
|
||||
$start = 1;
|
||||
$begins = -1;
|
||||
} else {
|
||||
while (($start < strlen($source)) && (substr($source, $start, 1) == "?")) {
|
||||
$start = $start + 1;
|
||||
$begins = $begins + 1;
|
||||
}
|
||||
}
|
||||
if ((substr($source, $end - 1, 1) == "*") && ($this->isEvenWildcards($source, $end - 1))) { //TODO
|
||||
$end = $end - 1;
|
||||
$ends = -1;
|
||||
} else {
|
||||
while (($end > 0) && substr($source, $end - 1, 1) == "?" && ($this->isEvenWildcards($source, $end - 1))) { //TODO
|
||||
$end = $end - 1;
|
||||
$ends = $ends + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$source = substr($source, $start, $end-$start);
|
||||
$index = -1;
|
||||
$leftover = strlen($target);
|
||||
while ($leftover > 0) {
|
||||
$index = strpos($target, $source, $index + 1);
|
||||
if ($index === false) {
|
||||
break;
|
||||
}
|
||||
$escapes = Utilities::countEscapeCharacters($target, 0, $index);
|
||||
if (($index > 0) && ($begins != -1) && ($begins < ($index - $escapes))) {
|
||||
break;
|
||||
}
|
||||
$escapes = Utilities::countEscapeCharacters($target, $index + 1, strlen($target));
|
||||
$leftover = strlen($target) - $index - $escapes - strlen($source);
|
||||
if (($leftover > 0) && (($ends != -1) && ($leftover > $ends))) {
|
||||
continue;
|
||||
}
|
||||
return Relation::SUPERSET;
|
||||
}
|
||||
return Relation::DISJOINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a string for the backslash character
|
||||
* @param $str string to search in
|
||||
* @param int $idx end index
|
||||
* @return true if the number of backslash characters is even, false if odd
|
||||
*/
|
||||
private function isEvenWildcards($str, $idx) {
|
||||
$result = 0;
|
||||
while (($idx > 0) && (strpos($str, "\\", $idx - 1)) !== false) {
|
||||
$idx = $idx - 1;
|
||||
$result = $result + 1;
|
||||
}
|
||||
return Utilities::isEvenNumber($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an Object is an instance of the String class
|
||||
* @param mixed $arg the var to test
|
||||
* @return bool true if arg is a string, false if not
|
||||
*/
|
||||
private function isString($arg) {
|
||||
return is_string($arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Static method to demonstrate this class.
|
||||
*/
|
||||
public static function test() {
|
||||
// Examples.
|
||||
$wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", "beta", new LogicalValue("ANY"), "sp2", null, null, null, null);
|
||||
$wfn2 = new WellFormedName("a", "microsoft", "internet_explorer", new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"));
|
||||
$cpenm = new CPENameMatcher();
|
||||
$cpenu = new CPENameUnbinder();
|
||||
$cpenb = new CPENameBinder();
|
||||
$wfn = $cpenu->unbindURI($cpenb->bindToURI($wfn));
|
||||
$wfn2 = $cpenu->unbindFS($cpenb->bindToFS($wfn2));
|
||||
var_dump($cpenm->isDisjoint($wfn, $wfn2)); // false
|
||||
var_dump($cpenm->isEqual($wfn, $wfn2)); // false
|
||||
var_dump($cpenm->isSubset($wfn, $wfn2)); // true, $wfn2 is a subset of wfn
|
||||
var_dump($cpenm->isSuperset($wfn, $wfn2)); // false
|
||||
$wfn = $cpenu->unbindFS("cpe:2.3:a:adobe:*:9.*:*:PalmOS:*:*:*:*:*");
|
||||
$wfn2 = $cpenu->unbindURI("cpe:/a::Reader:9.3.2:-:-");
|
||||
var_dump($cpenm->isDisjoint($wfn, $wfn2)); // true, $wfn2 and wfn are disjoint
|
||||
var_dump($cpenm->isEqual($wfn, $wfn2)); // false
|
||||
var_dump($cpenm->isSubset($wfn, $wfn2)); // false
|
||||
var_dump($cpenm->isSuperset($wfn, $wfn2)); // false
|
||||
}
|
||||
}
|
@ -8,27 +8,40 @@ use PacificSec\CPE\Common\LogicalValue;
|
||||
/**
|
||||
* The CPENameBinder class is a simple implementation
|
||||
* of the CPE Name binding algorithm, as specified in the
|
||||
* CPE Naming Standard version 2.3. It is based on Java version
|
||||
* CPE Naming Standard version 2.3.
|
||||
* It is based on Java version
|
||||
* implemented by Joshua Kraunelis <jkraunelis@mitre.org>.
|
||||
*
|
||||
* @see <a href="http://cpe.mitre.org">cpe.mitre.org</a> for more information.
|
||||
* @author Antonio Franco
|
||||
* @email antonio.franco@pacificsec.com
|
||||
*/
|
||||
class CPENameBinder {
|
||||
class CPENameBinder
|
||||
{
|
||||
|
||||
/**
|
||||
* Binds a {@link WellFormedName} object to a URI.
|
||||
* @param $w WellFormedName to be bound to URI
|
||||
* @return URI binding of WFN
|
||||
*
|
||||
* @param $w WellFormedName
|
||||
* to be bound to URI
|
||||
* @return string URI binding of WFN
|
||||
*/
|
||||
public function bindToURI(WellFormedName $w) {
|
||||
public function bindToURI(WellFormedName $w)
|
||||
{
|
||||
|
||||
// Initialize the output with the CPE v2.2 URI prefix.
|
||||
$uri = "cpe:/";
|
||||
|
||||
// Define the attributes that correspond to the seven components in a v2.2. CPE.
|
||||
$attributes = array("part", "vendor", "product", "version", "update", "edition", "language");
|
||||
$attributes = array(
|
||||
"part",
|
||||
"vendor",
|
||||
"product",
|
||||
"version",
|
||||
"update",
|
||||
"edition",
|
||||
"language"
|
||||
);
|
||||
|
||||
// Iterate over the well formed name
|
||||
foreach ($attributes as $a) {
|
||||
@ -56,15 +69,28 @@ class CPENameBinder {
|
||||
|
||||
/**
|
||||
* Top-level function used to bind WFN w to formatted string.
|
||||
* @param $w WellFormedName to bind
|
||||
* @return Formatted String
|
||||
*
|
||||
* @param $w WellFormedName
|
||||
* to bind
|
||||
* @return string Formatted String
|
||||
*/
|
||||
public function bindToFS(WellFormedName $w) {
|
||||
public function bindToFS(WellFormedName $w)
|
||||
{
|
||||
// Initialize the output with the CPE v2.3 string prefix.
|
||||
$fs = "cpe:2.3:";
|
||||
foreach (array("part", "vendor", "product", "version",
|
||||
"update", "edition", "language", "sw_edition", "target_sw",
|
||||
"target_hw", "other") as $a) {
|
||||
foreach (array(
|
||||
"part",
|
||||
"vendor",
|
||||
"product",
|
||||
"version",
|
||||
"update",
|
||||
"edition",
|
||||
"language",
|
||||
"sw_edition",
|
||||
"target_sw",
|
||||
"target_hw",
|
||||
"other"
|
||||
) as $a) {
|
||||
$v = $this->bindValueForFS($w->get($a));
|
||||
$fs = $fs . $v;
|
||||
// add a colon except at the very end
|
||||
@ -78,10 +104,13 @@ class CPENameBinder {
|
||||
/**
|
||||
* Convert the value v to its proper string representation for insertion to
|
||||
* formatted string.
|
||||
* @param $v value to convert
|
||||
* @return Formatted value
|
||||
*
|
||||
* @param mixed $v
|
||||
* value to convert
|
||||
* @return mixed Formatted value
|
||||
*/
|
||||
private function bindValueForFS($v) {
|
||||
private function bindValueForFS($v)
|
||||
{
|
||||
if ($v instanceof LogicalValue) {
|
||||
$l = $v;
|
||||
// The value NA binds to a blank.
|
||||
@ -97,30 +126,34 @@ class CPENameBinder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect each character in string s. Certain nonalpha characters pass
|
||||
* Inspect each character in string s.
|
||||
* Certain nonalpha characters pass
|
||||
* thru without escaping into the result, but most retain escaping.
|
||||
* @param $s
|
||||
*
|
||||
* @param
|
||||
* $s
|
||||
* @return
|
||||
*/
|
||||
private function processQuotedChars($s) {
|
||||
private function processQuotedChars($s)
|
||||
{
|
||||
$result = "";
|
||||
$idx = 0;
|
||||
while ($idx < strlen($s)) {
|
||||
$c = substr($s, $idx, 1);
|
||||
if ($c != "\\") {
|
||||
// unquoted characters pass thru unharmed.
|
||||
$result = $result . $c;
|
||||
$result .= $c;
|
||||
} else {
|
||||
// escaped characters are examined.
|
||||
$nextchr = substr($s, $idx + 1, 1);
|
||||
// the period, hyphen and underscore pass unharmed.
|
||||
if ($nextchr == "." || $nextchr == "-" || $nextchr == "_") {
|
||||
$result = $result . $nextchr;
|
||||
$result .= $nextchr;
|
||||
$idx = $idx + 2;
|
||||
continue;
|
||||
} else {
|
||||
// all others retain escaping.
|
||||
$result = $result . "\\" . $nextchr;
|
||||
$result .= "\\" . $nextchr;
|
||||
$idx = $idx + 2;
|
||||
continue;
|
||||
}
|
||||
@ -132,12 +165,16 @@ class CPENameBinder {
|
||||
|
||||
/**
|
||||
* Converts a string to the proper string for including in
|
||||
* a CPE v2.2-conformant URI. The logical value ANY binds
|
||||
* a CPE v2.2-conformant URI.
|
||||
* The logical value ANY binds
|
||||
* to the blank in the 2.2-conformant URI.
|
||||
* @param $s string to be converted
|
||||
* @return converted string
|
||||
*
|
||||
* @param $s string
|
||||
* to be converted
|
||||
* @return string converted string
|
||||
*/
|
||||
private function bindValueForURI($s) {
|
||||
private function bindValueForURI($s)
|
||||
{
|
||||
if ($s instanceof LogicalValue) {
|
||||
$l = $s;
|
||||
// The value NA binds to a blank.
|
||||
@ -159,10 +196,13 @@ class CPENameBinder {
|
||||
* - Pass alphanumeric characters thru untouched
|
||||
* - Percent-encode quoted non-alphanumerics as needed
|
||||
* - Unquoted special characters are mapped to their special forms
|
||||
* @param $s string to be transformed
|
||||
* @return transformed string
|
||||
*
|
||||
* @param $s string
|
||||
* to be transformed
|
||||
* @return string transformed string
|
||||
*/
|
||||
private function transformForURI($s) {
|
||||
private function transformForURI($s)
|
||||
{
|
||||
$result = "";
|
||||
$idx = 0;
|
||||
|
||||
@ -171,7 +211,7 @@ class CPENameBinder {
|
||||
$thischar = substr($s, $idx, 1);
|
||||
// Alphanumerics (incl. underscore) pass untouched.
|
||||
if (Utilities::isAlphanum($thischar)) {
|
||||
$result = $result . $thischar;
|
||||
$result .= $thischar;
|
||||
$idx = $idx + 1;
|
||||
continue;
|
||||
}
|
||||
@ -179,17 +219,17 @@ class CPENameBinder {
|
||||
if ($thischar == "\\") {
|
||||
$idx = $idx + 1;
|
||||
$nxtchar = substr($s, $idx, 1);
|
||||
$result = $result . $this->pctEncode($nxtchar);
|
||||
$result .= $this->pctEncode($nxtchar);
|
||||
$idx = $idx + 1;
|
||||
continue;
|
||||
}
|
||||
// Bind the unquoted '?' special character to "%01".
|
||||
if ($thischar == "?") {
|
||||
$result = $result . "%01";
|
||||
$result .= "%01";
|
||||
}
|
||||
// Bind the unquoted '*' special character to "%02".
|
||||
if ($thischar == "*") {
|
||||
$result = $result . "%02";
|
||||
$result .= "%02";
|
||||
}
|
||||
$idx = $idx + 1;
|
||||
}
|
||||
@ -199,121 +239,97 @@ class CPENameBinder {
|
||||
/**
|
||||
* Returns the appropriate percent-encoding of character c.
|
||||
* Certain characters are returned without encoding.
|
||||
* @param $c the single character string to be encoded
|
||||
* @return the percent encoded string
|
||||
*
|
||||
* @param string $c the
|
||||
* single character string to be encoded
|
||||
* @return string the percent encoded string
|
||||
*/
|
||||
private function pctEncode($c) {
|
||||
if ($c == "!") {
|
||||
private function pctEncode($c)
|
||||
{
|
||||
switch ($c) {
|
||||
case '!':
|
||||
return "%21";
|
||||
}
|
||||
if ($c == "\"") {
|
||||
case "\"":
|
||||
return "%22";
|
||||
}
|
||||
if ($c == "#") {
|
||||
case "#":
|
||||
return "%23";
|
||||
}
|
||||
if ($c == "$") {
|
||||
case "$":
|
||||
return "%24";
|
||||
}
|
||||
if ($c == "%") {
|
||||
case "%":
|
||||
return "%25";
|
||||
}
|
||||
if ($c == "&") {
|
||||
case "&":
|
||||
return "%26";
|
||||
}
|
||||
if ($c == "'") {
|
||||
case "'":
|
||||
return "%27";
|
||||
}
|
||||
if ($c == "(") {
|
||||
case "(":
|
||||
return "%28";
|
||||
}
|
||||
if ($c == ")") {
|
||||
case ")":
|
||||
return "%29";
|
||||
}
|
||||
if ($c == "*") {
|
||||
case "*":
|
||||
return "%2a";
|
||||
}
|
||||
if ($c == "+") {
|
||||
case "+":
|
||||
return "%2b";
|
||||
}
|
||||
if ($c == ",") {
|
||||
case ",":
|
||||
return "%2c";
|
||||
}
|
||||
// bound without encoding.
|
||||
if ($c == "-") {
|
||||
return $c;
|
||||
}
|
||||
// bound without encoding.
|
||||
if ($c == ".") {
|
||||
return $c;
|
||||
}
|
||||
if ($c == "/") {
|
||||
case "/":
|
||||
return "%2f";
|
||||
}
|
||||
if ($c == ":") {
|
||||
case ":":
|
||||
return "%3a";
|
||||
}
|
||||
if ($c == ";") {
|
||||
case ";":
|
||||
return "%3b";
|
||||
}
|
||||
if ($c == "<") {
|
||||
case "<":
|
||||
return "%3c";
|
||||
}
|
||||
if ($c == "=") {
|
||||
case "=":
|
||||
return "%3d";
|
||||
}
|
||||
if ($c == ">") {
|
||||
case ">":
|
||||
return "%3e";
|
||||
}
|
||||
if ($c == "?") {
|
||||
case "?":
|
||||
return "%3f";
|
||||
}
|
||||
if ($c == "@") {
|
||||
case "@":
|
||||
return "%40";
|
||||
}
|
||||
if ($c == "[") {
|
||||
case "[":
|
||||
return "%5b";
|
||||
}
|
||||
if ($c == "\\") {
|
||||
case "\\":
|
||||
return "%5c";
|
||||
}
|
||||
if ($c == "]") {
|
||||
case "]":
|
||||
return "%5d";
|
||||
}
|
||||
if ($c == "^") {
|
||||
case "^":
|
||||
return "%5e";
|
||||
}
|
||||
if ($c == "`") {
|
||||
case "`":
|
||||
return "%60";
|
||||
}
|
||||
if ($c == "{") {
|
||||
case "{":
|
||||
return "%7b";
|
||||
}
|
||||
if ($c == "|") {
|
||||
case "|":
|
||||
return "%7c";
|
||||
}
|
||||
if ($c == "}") {
|
||||
case "}":
|
||||
return "%7d";
|
||||
}
|
||||
if ($c == "~") {
|
||||
return "%7d";
|
||||
}
|
||||
// Shouldn't reach here, return original character
|
||||
case "~":
|
||||
return "%7e";
|
||||
default:
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the values of the five arguments into the single
|
||||
* edition component. If all the values are blank, the
|
||||
* edition component.
|
||||
* If all the values are blank, the
|
||||
* function returns a blank.
|
||||
* @param $ed edition string
|
||||
* @param $sw_ed software edition string
|
||||
* @param $t_sw target software string
|
||||
* @param $t_hw target hardware string
|
||||
* @param $oth other edition information string
|
||||
* @return the packed string, or blank
|
||||
*
|
||||
* @param string $ed edition
|
||||
* string
|
||||
* @param string $sw_ed software
|
||||
* edition string
|
||||
* @param string $t_sw target
|
||||
* software string
|
||||
* @param string $t_hw target
|
||||
* hardware string
|
||||
* @param string $oth other
|
||||
* edition information string
|
||||
* @return string the packed string, or blank
|
||||
*/
|
||||
private function pack($ed, $sw_ed, $t_sw, $t_hw, $oth) {
|
||||
private function pack($ed, $sw_ed, $t_sw, $t_hw, $oth)
|
||||
{
|
||||
if ($sw_ed == "" && $t_sw == "" && $t_hw == "" && $oth == "") {
|
||||
// All the extended attributes are blank, so don't do
|
||||
// any packing, just return ed.
|
||||
@ -326,13 +342,16 @@ class CPENameBinder {
|
||||
|
||||
/**
|
||||
* Removes trailing colons from the URI.
|
||||
* @param $s the string to be trimmed
|
||||
* @return the trimmed string
|
||||
*
|
||||
* @param string $s the
|
||||
* string to be trimmed
|
||||
* @return string the trimmed string
|
||||
*/
|
||||
private function trim($s) {
|
||||
private function trim($s)
|
||||
{
|
||||
$s1 = strrev($s);
|
||||
$idx = 0;
|
||||
for ($i = 0; $i != strlen($s1); $i++) {
|
||||
for ($i = 0; $i != strlen($s1); $i ++) {
|
||||
if (substr($s1, $i, 1) == ":") {
|
||||
$idx = $idx + 1;
|
||||
} else {
|
||||
@ -341,17 +360,17 @@ class CPENameBinder {
|
||||
}
|
||||
// Return the substring after all trailing colons,
|
||||
// reversed back to its original character order.
|
||||
return strrev(substr($s1, $idx, strlen($s1)-$idx));
|
||||
return strrev(substr($s1, $idx, strlen($s1) - $idx));
|
||||
}
|
||||
|
||||
/*
|
||||
* Static method to demonstrate this class.
|
||||
*/
|
||||
public static function test() {
|
||||
public static function test()
|
||||
{
|
||||
// A few examples.
|
||||
echo "Testing CPENamingBind...<br>\n";
|
||||
$wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001",
|
||||
"beta", new LogicalValue("ANY"), "sp2", null, null, null, null);
|
||||
$wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", "beta", new LogicalValue("ANY"), "sp2", null, null, null, null);
|
||||
$wfn2 = new WellFormedName();
|
||||
|
||||
$wfn2->set("part", "a");
|