Просмотр исходного кода

Add checksum states, to differentiate between a missing or invalid checksum

tags/0.9.0
Kilogitty 4 лет назад
committed by itismadness
Родитель
Сommit
a084b8a494
6 измененных файлов: 104 добавлений и 74 удалений
  1. +5
    -5
      README.md
  2. +53
    -0
      src/Checks/Checksum.php
  3. +11
    -0
      src/Checks/ChecksumStates.php
  4. +4
    -4
      src/Command/AnalyzeCommand.php
  5. +31
    -56
      src/Logchecker.php
  6. +0
    -9
      src/Util.php

+ 5
- 5
README.md Просмотреть файл

@@ -63,7 +63,7 @@ Help:

$ logchecker tests/logs/wgdbcm.log
Score : 57
Checksum: false
Checksum: checksum_missing
Details :
[Notice] Translated log from Русский (Russian) to English.
EAC version older than 0.99 (-30 points)
@@ -80,7 +80,7 @@ Details :

$logchecker = new OrpheusNET\Logchecker\Logchecker();
$logchecker->add_file('path/to/file.log');
list($score, $details, $checksum, $log_text) = $logchecker->parse();
list($score, $details, $checksum_state, $log_text) = $logchecker->parse();
```

## Library Usage
@@ -99,9 +99,9 @@ use OrpheusNET\Logchecker\Logchecker;

$logchecker = new Logchecker();
$logchecker->new_file('/path/to/log/file');
list($score, $details, $checksum, $log_text) = $logchecker->parse();
list($score, $details, $checksum_state, $log_text) = $logchecker->parse();
print('Score: ' . $score . "\n");
print('Checksum: ' . ($checksum ? 'true' : 'false') . "\n");
print('Checksum: ' . $checksum_state . "\n");
print("\nDetails:\n");
foreach ($details as $detail) {
print(" {$detail}\n");
@@ -118,4 +118,4 @@ git clone https://github.com/OPSnet/Logchecker
cd Logchecker
composer install
php -d phar.readonly=0 bin/compile
```
```

+ 53
- 0
src/Checks/Checksum.php Просмотреть файл

@@ -0,0 +1,53 @@
<?php

namespace OrpheusNET\Logchecker\Checks;

use OrpheusNET\Logchecker\Util;

class Checksum {
/**
* Will return the checksum status of the given logfile,
* see ChecksumStates.php for the possible values.
*/
public static function validate(string $logPath, $EAC) {
if ($EAC) {
$command = 'eac_logchecker';
$noChecksumResult = 'Log entry has no checksum!';
$invalidResult = 'Log entry was modified, checksum incorrect!';
$goodString = 'Log entry is fine!';
} else {
$command = 'xld_logchecker';
$noChecksumResult = 'Not a logfile';
$invalidResult = 'Malformed';
$goodResult = 'OK';
}

if (logchecker_exist($command)) {
$output = shell_exec("{$command} " . escapeshellarg($logPath));
if (strpos($output, $goodResult) === false) {
if($output == null) {
return ChecksumStates::CHECKSUM_MISSING;
}

if(strpos($output, $noChecksumResult) !== false) {
return ChecksumStates::CHECKSUM_MISSING;
}
if(strpos($output, $invalidResult) !== false) {
return ChecksumStates::CHECKSUM_INVALID;
}
}
}

return ChecksumStates::CHECKSUM_OK;
}

public static function logchecker_exist($EAC) {
if ($EAC) {
$command = 'eac_logchecker';
} else {
$command = 'xld_logchecker';
}

return Util::commandExists($command);
}
}

+ 11
- 0
src/Checks/ChecksumStates.php Просмотреть файл

@@ -0,0 +1,11 @@
<?php

namespace OrpheusNET\Logchecker\Checks;

use OrpheusNET\Logchecker\Util;

class ChecksumStates {
const CHECKSUM_MISSING = 'checksum_missing';
const CHECKSUM_INVALID = 'checksum_invalid';
const CHECKSUM_OK = 'checksum_ok';
}

+ 4
- 4
src/Command/AnalyzeCommand.php Просмотреть файл

@@ -24,14 +24,14 @@ class AnalyzeCommand extends Command {
$output->writeln("Invalid file");
return;
}
$logchecker = new Logchecker();
$logchecker->new_file($filename);
list($score, $details, $checksum, $log_text) = $logchecker->parse();
list($score, $details, $checksumState, $log_text) = $logchecker->parse();
$output->writeln('Ripper : ' . $logchecker->get_ripper());
$output->writeln('Version : ' . $logchecker->get_version());
$output->writeln('Score : ' . $score);
$output->writeln('Checksum: ' . ($checksum ? 'true' : 'false'));
$output->writeln('Checksum: ' . $checksumState);

if (count($details) > 0) {
$output->writeln('Details :');
@@ -103,4 +103,4 @@ HTML;
file_put_contents($input->getOption('out'), $html_out);
}
}
}
}

+ 31
- 56
src/Logchecker.php Просмотреть файл

@@ -14,7 +14,7 @@ class Logchecker {
var $LogPath = null;
var $Logs = array();
var $Tracks = array();
var $Checksum = true;
var $checksumStatus = Checks\ChecksumStates::CHECKSUM_OK;
var $Score = 100;
var $Details = array();
var $Offsets = array();
@@ -81,7 +81,7 @@ class Logchecker {
$this->LogPath = null;
$this->Logs = array();
$this->Tracks = array();
$this->Checksum = true;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_OK;
$this->Score = 100;
$this->Details = array();
$this->Offsets = array();
@@ -154,7 +154,7 @@ class Logchecker {
$this->account('Could not detect log encoding, log is corrupt.');
return $this->return_parse();
}
if (strpos($this->Log, "Log created by: whipper") !== false) {
return $this->whipper_parse();
}
@@ -194,16 +194,16 @@ class Logchecker {
$Hash = $Yaml['SHA-256 hash'];
$Lines = explode("\n", trim($this->Log));
$Slice = array_slice($Lines, 0, count($Lines)-1);
$this->Checksum = strtolower(hash('sha256', implode("\n", $Slice))) === strtolower($Hash);
$this->checksumStatus = strtolower(hash('sha256', implode("\n", $Slice))) === strtolower($Hash);
unset($Slice);
unset($Lines);
$Class = $this->Checksum ? 'good' : 'bad';
$Class = $this->checksumStatus ? 'good' : 'bad';
$Yaml['SHA-256 hash'] = "<span class='{$Class}'>{$Hash}</span>";
}
else {
$this->Checksum = false;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
}
$Drive = $Yaml['Ripping phase information']['Drive'];
$Offset = $Yaml['Ripping phase information']['Read offset correction'];

@@ -215,7 +215,7 @@ class Logchecker {
$this->get_drives($Drive);

$DriveClass = 'badish';
if (count($this->Drives) > 0) {
$DriveClass = 'good';
if (in_array((string) $Offset, $this->Offsets)) {
@@ -359,7 +359,7 @@ class Logchecker {
} elseif (preg_match("/[\-]+BEGIN XLD SIGNATURE[\S\n\-]+END XLD SIGNATURE[\-]+/i", $this->Log)) { // xld checksum (plugin)
$this->Logs = preg_split("/(\n[\-]+BEGIN XLD SIGNATURE[\S\n\-]+END XLD SIGNATURE[\-]+)/i", $this->Log, -1, PREG_SPLIT_DELIM_CAPTURE);
} else { //no checksum
$this->Checksum = false;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
$this->Logs = preg_split("/(\nEnd of status report)/i", $this->Log, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($this->Logs as $Key => $Value) {
if (preg_match("/---- CUETools DB Plugin V.+/i", $Value)) {
@@ -374,13 +374,13 @@ class Logchecker {
unset($this->Logs[$Key]);
} //strip empty
//append stat msgs
elseif (!$this->Checksum && preg_match("/End of status report/i", $Log)) {
elseif ($this->checksumStatus !== Checks\ChecksumStates::CHECKSUM_OK && preg_match("/End of status report/i", $Log)) {
$this->Logs[$Key - 1] .= $Log;
unset($this->Logs[$Key]);
} elseif ($this->Checksum && preg_match("/[\=]+\s+Log checksum/i", $Log)) {
} elseif ($this->checksumStatus === Checks\ChecksumStates::CHECKSUM_OK && preg_match("/[\=]+\s+Log checksum/i", $Log)) {
$this->Logs[$Key - 1] .= $Log;
unset($this->Logs[$Key]);
} elseif ($this->Checksum && preg_match("/[\-]+BEGIN XLD SIGNATURE/i", $Log)) {
} elseif ($this->checksumStatus === Checks\ChecksumStates::CHECKSUM_OK && preg_match("/[\-]+BEGIN XLD SIGNATURE/i", $Log)) {
$this->Logs[$Key - 1] .= $Log;
unset($this->Logs[$Key]);
}
@@ -395,32 +395,25 @@ class Logchecker {
$CurrScore = $this->Score;
$Log = preg_replace('/(\=+\s+Log checksum.*)/i', '<span class="good">$1</span>', $Log, 1, $Count);
if (preg_match('/Exact Audio Copy (.+) from/i', $Log, $Matches)) { //eac v1 & checksum
// we set $this->Checksum to true here as these torrents are already trumpable by virtue of a bad score
if ($Matches[1]) {
$this->Version = floatval(explode(" ", substr($Matches[1], 1))[0]);
if ($this->Version <= 0.95) {
$this->Checksum = false;
$this->account("EAC version older than 0.99", 30);
}

if ($this->Version < 1) {
$this->Checksum = false;
}
elseif ($this->Version >= 1 && $Count) {
$this->Checksum = $this->Checksum && true;
}
else {
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
if ($this->Version <= 0.95) {
# EAC 0.95 and before was missing a handful of stuff for full log validation that 0.99 included (-30 points)
$this->account("EAC version older than 0.99", 30);
}
} else {
// Above version 1 and no checksum
$this->Checksum = false;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
}
}
else {
$this->Checksum = false;
} else {
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
$this->account("EAC version older than 0.99", 30);
}
}
elseif (preg_match('/EAC extraction logfile from/i', $Log)) {
$this->Checksum = false;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
$this->account("EAC version older than 0.99", 30);
}

@@ -428,12 +421,9 @@ class Logchecker {
if (preg_match('/X Lossless Decoder version (\d+) \((.+)\)/i', $Log, $Matches)) { //xld version & checksum
$this->Version = $Matches[1];
if ($this->Version >= 20121222 && !$Count) {
$this->Checksum = false;
$this->checksumStatus = Checks\ChecksumStates::CHECKSUM_MISSING;
//$this->account('No checksum with XLD 20121222 or newer', 15);
}
else {
$this->Checksum = $this->Checksum && true;
}
}
$Log = preg_replace('/Exact Audio Copy (.+) from (.+)/i', 'Exact Audio Copy <span class="log1">$1</span> from <span class="log1">$2</span>', $Log, 1, $Count);
$Log = preg_replace("/EAC extraction logfile from (.+)\n+(.+)/i", "<span class=\"good\">EAC extraction logfile from <span class=\"log5\">$1</span></span>\n\n<span class=\"log4\">$2</span>", $Log, 1, $EAC);
@@ -453,26 +443,11 @@ class Logchecker {
$this->RIPPER = ($EAC) ? "EAC" : "XLD";
}

if ($this->ValidateChecksum && $this->Checksum && !empty($this->LogPath)) {
if ($EAC) {
$Command = 'eac_logchecker';
$BadStrings = ['Log entry has no checksum!', 'Log entry was modified, checksum incorrect!'];
$GoodString = 'Log entry is fine!';
}
else {
$Command = 'xld_logchecker';
$BadStrings = ['Malformed', 'Not a logfile'];
$GoodString = 'OK';
}

if (Util::commandExists($Command)) {
$Out = shell_exec("{$Command} ".escapeshellarg($this->LogPath));
if ($Out == null || Util::strposArray($Out, $BadStrings) !== false || strpos($Out, $GoodString) === false) {
$this->Checksum = false;
}
}
else {
$this->account("Could not find {$Command}, checksum not validated.", false, false, false, true);
if ($this->ValidateChecksum && $this->checksumStatus == Checks\ChecksumStates::CHECKSUM_OK && !empty($this->LogPath)) {
if (Checks\Checksum::logchecker_exist($EAC)){
$this->checksumStatus = Checks\Checksum::validate($this->LogPath, $EAC);
} else {
$this->account("Could not find {$this->RIPPER} logchecker, checksum not validated.", false, false, false, true);
}
}

@@ -1484,12 +1459,12 @@ class Logchecker {
}

function return_parse() {
return array(
return [
$this->Score,
$this->Details,
$this->Checksum,
$this->checksumStatus,
$this->Log
);
];
}

function get_ripper() {


+ 0
- 9
src/Util.php Просмотреть файл

@@ -9,13 +9,4 @@ class Util {
exec("{$where} {$cmd} 2>/dev/null", $output, $return_var);
return $return_var === 0;
}

public static function strposArray(string $haystack, array $needles) {
foreach ($needles as $needle) {
if (($pos = strpos($haystack, $needle)) !== false) {
return $pos;
}
}
return false;
}
}

Загрузка…
Отмена
Сохранить