Skip to content

add strict types #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions lib/ASN1/ASNObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);

namespace FG\ASN1;

Expand Down Expand Up @@ -37,21 +38,22 @@
use FG\ASN1\Universal\ObjectDescriptor;
use FG\Utility\BigInteger;
use LogicException;
use Stringable;

/**
* Class ASNObject is the base class for all concrete ASN.1 objects.
*/
abstract class ASNObject implements Parsable
abstract class ASNObject implements Parsable, Stringable
{
private $contentLength;
private $nrOfLengthOctets;
private ?int $contentLength = null;
private ?int $nrOfLengthOctets = null;

/**
* Must return the number of octets of the content part.
*
* @return int
*/
abstract protected function calculateContentLength();
abstract protected function calculateContentLength(): int;

/**
* Encode the object using DER encoding.
Expand All @@ -60,15 +62,15 @@ abstract protected function calculateContentLength();
*
* @return string the binary representation of an objects value
*/
abstract protected function getEncodedValue();
abstract protected function getEncodedValue(): ?string;

/**
* Return the content of this object in a non encoded form.
* This can be used to print the value in human readable form.
* This can be used to print the value in human-readable form.
*
* @return mixed
*/
abstract public function getContent();
abstract public function getContent(): mixed;

/**
* Return the object type octet.
Expand All @@ -78,7 +80,7 @@ abstract public function getContent();
*
* @return int
*/
abstract public function getType();
abstract public function getType(): int;

/**
* Returns all identifier octets. If an inheriting class models a tag with
Expand All @@ -89,7 +91,7 @@ abstract public function getType();
*
* @return string Identifier as a set of octets
*/
public function getIdentifier()
public function getIdentifier(): string
{
$firstOctet = $this->getType();

Expand All @@ -105,7 +107,7 @@ public function getIdentifier()
*
* @return string the full binary representation of the complete object
*/
public function getBinary()
public function getBinary(): string
{
$result = $this->getIdentifier();
$result .= $this->createLengthPart();
Expand All @@ -114,7 +116,7 @@ public function getBinary()
return $result;
}

private function createLengthPart()
private function createLengthPart(): string
{
$contentLength = $this->getContentLength();
$nrOfLengthOctets = $this->getNumberOfLengthOctets($contentLength);
Expand All @@ -132,9 +134,9 @@ private function createLengthPart()
}
}

protected function getNumberOfLengthOctets($contentLength = null)
protected function getNumberOfLengthOctets(int $contentLength = null): int
{
if (!isset($this->nrOfLengthOctets)) {
if ($this->nrOfLengthOctets === null) {
if ($contentLength == null) {
$contentLength = $this->getContentLength();
}
Expand All @@ -151,16 +153,16 @@ protected function getNumberOfLengthOctets($contentLength = null)
return $this->nrOfLengthOctets;
}

protected function getContentLength()
protected function getContentLength(): int
{
if (!isset($this->contentLength)) {
if ($this->contentLength === null) {
$this->contentLength = $this->calculateContentLength();
}

return $this->contentLength;
}

protected function setContentLength($newContentLength)
protected function setContentLength(int $newContentLength): void
{
$this->contentLength = $newContentLength;
$this->getNumberOfLengthOctets($newContentLength);
Expand All @@ -169,7 +171,7 @@ protected function setContentLength($newContentLength)
/**
* Returns the length of the whole object (including the identifier and length octets).
*/
public function getObjectLength()
public function getObjectLength(): int
{
$nrOfIdentifierOctets = strlen($this->getIdentifier());
$contentLength = $this->getContentLength();
Expand All @@ -178,7 +180,7 @@ public function getObjectLength()
return $nrOfIdentifierOctets + $nrOfLengthOctets + $contentLength;
}

public function __toString()
public function __toString(): string
{
return $this->getContent();
}
Expand All @@ -188,7 +190,7 @@ public function __toString()
*
* @see Identifier::getName()
*/
public function getTypeName()
public function getTypeName(): string
{
return Identifier::getName($this->getType());
}
Expand All @@ -201,7 +203,7 @@ public function getTypeName()
*
* @return \FG\ASN1\ASNObject
*/
public static function fromBinary(&$binaryData, &$offsetIndex = 0)
public static function fromBinary(string &$binaryData, ?int &$offsetIndex = 0): static
{
if (strlen($binaryData) <= $offsetIndex) {
throw new ParserException('Can not parse binary from data: Offset index larger than input size', $offsetIndex);
Expand Down
40 changes: 18 additions & 22 deletions lib/ASN1/AbstractString.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,88 +7,84 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);

namespace FG\ASN1;

use Exception;

abstract class AbstractString extends ASNObject implements Parsable
{
/** @var string */
protected $value;
private $checkStringForIllegalChars = true;
private $allowedCharacters = [];
private bool $checkStringForIllegalChars = true;
private array $allowedCharacters = [];

/**
* The abstract base class for ASN.1 classes which represent some string of character.
*
* @param string $string
*/
public function __construct($string)
public function __construct(protected string $value)
{
$this->value = $string;
}

public function getContent()
public function getContent(): string
{
return $this->value;
}

protected function allowCharacter($character)
protected function allowCharacter(string $character): void
{
$this->allowedCharacters[] = $character;
}

protected function allowCharacters(...$characters)
protected function allowCharacters(string ...$characters): void
{
foreach ($characters as $character) {
$this->allowedCharacters[] = $character;
}
}

protected function allowNumbers()
protected function allowNumbers(): void
{
foreach (range('0', '9') as $char) {
$this->allowedCharacters[] = (string) $char;
}
}

protected function allowAllLetters()
protected function allowAllLetters(): void
{
$this->allowSmallLetters();
$this->allowCapitalLetters();
}

protected function allowSmallLetters()
protected function allowSmallLetters(): void
{
foreach (range('a', 'z') as $char) {
$this->allowedCharacters[] = $char;
}
}

protected function allowCapitalLetters()
protected function allowCapitalLetters(): void
{
foreach (range('A', 'Z') as $char) {
$this->allowedCharacters[] = $char;
}
}

protected function allowSpaces()
protected function allowSpaces(): void
{
$this->allowedCharacters[] = ' ';
}

protected function allowAll()
protected function allowAll(): void
{
$this->checkStringForIllegalChars = false;
}

protected function calculateContentLength()
protected function calculateContentLength(): int
{
return strlen($this->value);
}

protected function getEncodedValue()
protected function getEncodedValue(): ?string
{
if ($this->checkStringForIllegalChars) {
$this->checkString();
Expand All @@ -97,18 +93,18 @@ protected function getEncodedValue()
return $this->value;
}

protected function checkString()
protected function checkString(): void
{
$stringLength = $this->getContentLength();
for ($i = 0; $i < $stringLength; $i++) {
if (in_array($this->value[$i], $this->allowedCharacters) == false) {
if (in_array($this->value[$i], $this->allowedCharacters) === false) {
$typeName = Identifier::getName($this->getType());
throw new Exception("Could not create a {$typeName} from the character sequence '{$this->value}'.");
}
}
}

public static function fromBinary(&$binaryData, &$offsetIndex = 0)
public static function fromBinary(string &$binaryData, ?int &$offsetIndex = 0): static
{
$parsedObject = new static('');

Expand Down
17 changes: 9 additions & 8 deletions lib/ASN1/AbstractTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);

namespace FG\ASN1;

use DateInterval;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Exception;

abstract class AbstractTime extends ASNObject
{
/** @var DateTime */
protected $value;
protected DateTimeInterface $value;

public function __construct($dateTime = null, $dateTimeZone = 'UTC')
public function __construct(null|string|\DateTimeInterface $dateTime = null, $dateTimeZone = 'UTC')
{
if ($dateTime == null || is_string($dateTime)) {
if (is_null($dateTime)) {
$dateTime = 'NOW';
}
$timeZone = new DateTimeZone($dateTimeZone);
$dateTimeObject = new DateTime($dateTime, $timeZone);
if ($dateTimeObject == false) {
if ($dateTimeObject === false) {
$errorMessage = $this->getLastDateTimeErrors();
$className = Identifier::getName($this->getType());
throw new Exception(sprintf("Could not create %s from date time string '%s': %s", $className, $dateTime, $errorMessage));
Expand All @@ -41,12 +42,12 @@ public function __construct($dateTime = null, $dateTimeZone = 'UTC')
$this->value = $dateTime;
}

public function getContent()
public function getContent(): \DateTimeInterface
{
return $this->value;
}

protected function getLastDateTimeErrors()
protected function getLastDateTimeErrors(): string
{
$messages = '';
$lastErrors = DateTime::getLastErrors() ?: ['errors' => []];
Expand All @@ -57,12 +58,12 @@ protected function getLastDateTimeErrors()
return substr($messages, 0, -2);
}

public function __toString()
public function __toString(): string
{
return $this->value->format("Y-m-d\tH:i:s");
}

protected static function extractTimeZoneData(&$binaryData, &$offsetIndex, DateTime $dateTime)
protected static function extractTimeZoneData(&$binaryData, &$offsetIndex, DateTime $dateTime): \DateTimeInterface
{
$sign = $binaryData[$offsetIndex++];
$timeOffsetHours = intval(substr($binaryData, $offsetIndex, 2));
Expand Down
14 changes: 3 additions & 11 deletions lib/ASN1/Base128.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);

namespace FG\ASN1;

Expand All @@ -10,12 +11,7 @@
*/
class Base128
{
/**
* @param int $value
*
* @return string
*/
public static function encode($value)
public static function encode(int $value): string
{
$value = BigInteger::create($value);
$octets = chr($value->modulus(0x80)->toInteger());
Expand All @@ -30,13 +26,9 @@ public static function encode($value)
}

/**
* @param string $octets
*
* @throws InvalidArgumentException if the given octets represent a malformed base-128 value or the decoded value would exceed the the maximum integer length
*
* @return int
*/
public static function decode($octets)
public static function decode(string $octets): string
{
$bitsPerOctet = 7;
$value = BigInteger::create(0);
Expand Down
Loading
Loading