Skip to content

Commit

Permalink
Exceptions rework
Browse files Browse the repository at this point in the history
  • Loading branch information
arokettu committed Jul 28, 2024
1 parent 027d249 commit 06b63b7
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 45 deletions.
9 changes: 9 additions & 0 deletions src/Exception/DomainException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Arokettu\Torrent\Exception;

class DomainException extends \DomainException implements TorrentFileException
{
}
9 changes: 9 additions & 0 deletions src/Exception/UnexpectedValueException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Arokettu\Torrent\Exception;

class UnexpectedValueException extends \UnexpectedValueException implements TorrentFileException
{
}
6 changes: 3 additions & 3 deletions src/FileSystem/FileData.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Arokettu\Torrent\FileSystem;

use Arokettu\Bencode\Bencode;
use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\DomainException;
use Arokettu\Torrent\Exception\PathNotFoundException;
use Arokettu\Torrent\Helpers\MathHelper;
use Arokettu\Torrent\MetaVersion;
Expand Down Expand Up @@ -60,7 +60,7 @@ public static function forPath(
[MetaVersion::V2, MetaVersion::V1],
=> new HybridV1V2\FileData(...$params, ...array_values($version)),
default
=> throw new InvalidArgumentException('Invalid metadata version'),
=> throw new DomainException('Invalid metadata version'),
};
}

Expand All @@ -73,7 +73,7 @@ protected function __construct(
protected bool $detectSymlinks,
) {
if ($pieceLength < self::PIECE_LENGTH_MIN || !MathHelper::isPow2($pieceLength)) {
throw new InvalidArgumentException(
throw new DomainException(
'pieceLength must be a power of 2 and at least ' . self::PIECE_LENGTH_MIN
);
}
Expand Down
3 changes: 1 addition & 2 deletions src/Helpers/CertHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Arokettu\Torrent\Helpers;

use Arokettu\Torrent\Exception\RuntimeException;
use OpenSSLCertificate;

/**
Expand All @@ -17,7 +16,7 @@ private static function assertOpenSSL(): void
if (\extension_loaded('openssl') === false) {
// @codeCoverageIgnoreStart
// coverage is generated with openssl
throw new RuntimeException('OpenSSL extension is not installed');
throw new \LogicException('OpenSSL extension is not installed');
// @codeCoverageIgnoreEnd
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/TorrentFile/Common/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\TorrentFile\Common;

use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\UnexpectedValueException;

/**
* @property-read bool $x
Expand Down Expand Up @@ -45,7 +45,7 @@ public function __construct(string $attr)
public function has(string $attr): bool
{
if (\strlen($attr) !== 1) {
throw new InvalidArgumentException('Attribute name must be 1 character long');
throw new UnexpectedValueException('Attribute name must be 1 character long');
}
return str_contains($this->attr, $attr);
}
Expand Down
4 changes: 2 additions & 2 deletions src/TorrentFile/DataMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Arokettu\Torrent\TorrentFile;

use Arokettu\Torrent\DataTypes\Internal\DictObject;
use Arokettu\Torrent\Exception\RuntimeException;
use Arokettu\Torrent\Exception\BadMethodCallException;

/**
* @internal
Expand Down Expand Up @@ -41,7 +41,7 @@ private function getInfoField(string $key): mixed
private function setInfoField(string $key, mixed $value): void
{
if ($this->isSigned()) {
throw new RuntimeException(
throw new BadMethodCallException(
'Unable to modify infohash fields of a signed torrent. ' .
'Please remove the signatures first'
);
Expand Down
11 changes: 6 additions & 5 deletions src/TorrentFile/InfoMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

use Arokettu\Bencode\Types\DictType;
use Arokettu\Torrent\DataTypes\Internal\InfoDict;
use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\BadMethodCallException;
use Arokettu\Torrent\Exception\UnexpectedValueException;
use Arokettu\Torrent\MetaVersion;

/**
Expand Down Expand Up @@ -36,10 +37,10 @@ public function isPrivate(): bool
public function setName(string $name): self
{
if ($name === '') {
throw new InvalidArgumentException('$name must not be empty');
throw new UnexpectedValueException('$name must not be empty');
}
if (str_contains($name, '/') || str_contains($name, "\0")) {
throw new InvalidArgumentException('$name must not contain slashes and zero bytes');
throw new UnexpectedValueException('$name must not contain slashes and zero bytes');
}

$this->setInfoField('name', $name);
Expand Down Expand Up @@ -102,7 +103,7 @@ private function resetInfoDict(): void
public function removeMetadata(MetaVersion $version): void
{
if (array_filter($this->getMetadataVersions(), fn ($v) => $v !== $version) === []) {
throw new InvalidArgumentException('Unable to remove the only remaining metadata');
throw new BadMethodCallException('Unable to remove the only remaining metadata');
}

match ($version) {
Expand All @@ -114,7 +115,7 @@ public function removeMetadata(MetaVersion $version): void
public function keepOnlyMetadata(MetaVersion $version): void
{
if (!$this->hasMetadata($version)) {
throw new InvalidArgumentException('Unable to keep metadata that is not present');
throw new BadMethodCallException('Unable to keep metadata that is not present');
}

match ($version) {
Expand Down
7 changes: 4 additions & 3 deletions src/TorrentFile/SignatureMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Arokettu\Torrent\DataTypes\Signature;
use Arokettu\Torrent\DataTypes\SignatureValidatorResult;
use Arokettu\Torrent\Exception\RuntimeException;
use Arokettu\Torrent\Exception\UnexpectedValueException;
use Arokettu\Torrent\Helpers\CertHelper;
use OpenSSLAsymmetricKey;
use OpenSSLCertificate;
Expand Down Expand Up @@ -56,12 +57,12 @@ public function sign(
iterable $info = [],
): void {
if (!openssl_x509_check_private_key($certificate, $key)) {
throw new RuntimeException('The key does not correspond to the certificate');
throw new UnexpectedValueException('The key does not correspond to the certificate');
}

$certData = openssl_x509_parse($certificate);
$commonName = $certData['subject']['CN'] ??
throw new RuntimeException('The certificate must contain a common name');
throw new UnexpectedValueException('The certificate must contain a common name');

$signInfo = new DictObject($info);

Expand Down Expand Up @@ -92,7 +93,7 @@ public function verifySignature(OpenSSLCertificate $certificate): SignatureValid
{
$certData = openssl_x509_parse($certificate);
$commonName = $certData['subject']['CN'] ??
throw new RuntimeException('The certificate must contain a common name');
throw new UnexpectedValueException('The certificate must contain a common name');

$signatures = $this->getSignatures();
/** @var Signature $signature */
Expand Down
6 changes: 3 additions & 3 deletions tests/files/AttributesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\Tests\Files;

use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\UnexpectedValueException;
use Arokettu\Torrent\TorrentFile\Common\Attributes;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -62,15 +62,15 @@ public function testPad(): void

public function testHasOneCharOnly(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('Attribute name must be 1 character long');

(new Attributes('xx'))->has('xx');
}

public function testAttrOneCharOnly(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('Attribute name must be 1 character long');

(new Attributes('xx'))->xx;
Expand Down
6 changes: 3 additions & 3 deletions tests/files/CreateFileV1FeaturesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\Tests\Files;

use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\BadMethodCallException;
use Arokettu\Torrent\MetaVersion;
use Arokettu\Torrent\TorrentFile;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -435,7 +435,7 @@ public function testUnableToDeleteV1(): void
{
$torrent = TorrentFile::fromPath(TEST_ROOT . '/data/files2', version: MetaVersion::V1);

$this->expectException(InvalidArgumentException::class);
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('Unable to remove the only remaining metadata');
$torrent->removeMetadata(MetaVersion::V1);
}
Expand All @@ -444,7 +444,7 @@ public function testUnableKeepV2(): void
{
$torrent = TorrentFile::fromPath(TEST_ROOT . '/data/files2', version: MetaVersion::V1);

$this->expectException(InvalidArgumentException::class);
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('Unable to keep metadata that is not present');
$torrent->keepOnlyMetadata(MetaVersion::V2);
}
Expand Down
6 changes: 3 additions & 3 deletions tests/files/CreateFileV1Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\Tests\Files;

use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\DomainException;
use Arokettu\Torrent\Exception\PathNotFoundException;
use Arokettu\Torrent\MetaVersion;
use Arokettu\Torrent\TorrentFile;
Expand Down Expand Up @@ -238,7 +238,7 @@ public function testNotFoundException(): void

public function testChunkTooSmall(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(DomainException::class);
$this->expectExceptionMessage('pieceLength must be a power of 2 and at least 16384');

TorrentFile::fromPath(
Expand All @@ -250,7 +250,7 @@ public function testChunkTooSmall(): void

public function testChunkNotPow2(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(DomainException::class);
$this->expectExceptionMessage('pieceLength must be a power of 2 and at least 16384');

TorrentFile::fromPath(
Expand Down
6 changes: 3 additions & 3 deletions tests/files/CreateFileV2FeaturesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\Tests\Files;

use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\BadMethodCallException;
use Arokettu\Torrent\MetaVersion;
use Arokettu\Torrent\TorrentFile;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -211,7 +211,7 @@ public function testUnableToDeleteV2(): void
{
$torrent = TorrentFile::fromPath(TEST_ROOT . '/data/files2', version: MetaVersion::V2);

$this->expectException(InvalidArgumentException::class);
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('Unable to remove the only remaining metadata');
$torrent->removeMetadata(MetaVersion::V2);
}
Expand All @@ -220,7 +220,7 @@ public function testUnableKeepV1(): void
{
$torrent = TorrentFile::fromPath(TEST_ROOT . '/data/files2', version: MetaVersion::V2);

$this->expectException(InvalidArgumentException::class);
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('Unable to keep metadata that is not present');
$torrent->keepOnlyMetadata(MetaVersion::V1);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/info/ImmutableWhenSignedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Arokettu\Torrent\Tests\Info;

use Arokettu\Torrent\Exception\RuntimeException;
use Arokettu\Torrent\Exception\BadMethodCallException;
use Arokettu\Torrent\TorrentFile;
use PHPUnit\Framework\TestCase;

Expand All @@ -14,7 +14,7 @@ class ImmutableWhenSignedTest extends TestCase
{
public function testImmutableWhenSigned(): void
{
$this->expectException(RuntimeException::class);
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage(
'Unable to modify infohash fields of a signed torrent. Please remove the signatures first'
);
Expand Down
8 changes: 4 additions & 4 deletions tests/info/NameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Arokettu\Torrent\Tests\Info;

use Arokettu\Bencode\Bencode;
use Arokettu\Torrent\Exception\InvalidArgumentException;
use Arokettu\Torrent\Exception\UnexpectedValueException;
use Arokettu\Torrent\TorrentFile;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -37,21 +37,21 @@ public function testNameSet(): void

public function testNotEmpty(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(UnexpectedValueException::class);
$torrent = TorrentFile::loadFromString('de');
$torrent->setName('');
}

public function testNoZeros(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(UnexpectedValueException::class);
$torrent = TorrentFile::loadFromString('de');
$torrent->setName("Test\0");
}

public function testNoSlashes(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectException(UnexpectedValueException::class);
$torrent = TorrentFile::loadFromString('de');
$torrent->setName('te/st');
}
Expand Down
20 changes: 10 additions & 10 deletions tests/sign/SignatureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Arokettu\Torrent\DataTypes\Signature;
use Arokettu\Torrent\DataTypes\SignatureValidatorResult;
use Arokettu\Torrent\Exception\RuntimeException;
use Arokettu\Torrent\Exception\UnexpectedValueException;
use Arokettu\Torrent\TorrentFile;
use OpenSSLCertificate;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -78,11 +78,11 @@ public function testVerifySignaturesNoSignature(): void

public function testVerifySignaturesMustBeCN(): void
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('The certificate must contain a common name');

$file = TorrentFile::load(TEST_ROOT . '/data/CentOS-7-x86_64-NetInstall-1611-signed.torrent');

$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('The certificate must contain a common name');

$cert1 = openssl_x509_read('file://' . TEST_ROOT . '/data/keys/test1-nocn.crt');
self::assertEquals(SignatureValidatorResult::NotPresent, $file->verifySignature($cert1));
}
Expand Down Expand Up @@ -124,27 +124,27 @@ public function testSignNoCert(): void

public function testSignMustHaveCN(): void
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('The certificate must contain a common name');

$file = TorrentFile::load(TEST_ROOT . '/data/CentOS-7-x86_64-NetInstall-1611.torrent');

$cert = openssl_x509_read('file://' . TEST_ROOT . '/data/keys/test1-nocn.crt');
$key = openssl_pkey_get_private('file://' . TEST_ROOT . '/data/keys/test1.key');

$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('The certificate must contain a common name');

$file->sign($key, $cert);
}

public function testSignCertKeyMatch(): void
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('The key does not correspond to the certificate');

$file = TorrentFile::load(TEST_ROOT . '/data/CentOS-7-x86_64-NetInstall-1611.torrent');

$cert = openssl_x509_read('file://' . TEST_ROOT . '/data/keys/test2.crt');
$key = openssl_pkey_get_private('file://' . TEST_ROOT . '/data/keys/test1.key');

$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage('The key does not correspond to the certificate');

$file->sign($key, $cert);
}

Expand Down

0 comments on commit 06b63b7

Please sign in to comment.