Skip to content
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

Bring Project and CI Up-to-date #89

Merged
merged 10 commits into from
Apr 2, 2024
Merged
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
14 changes: 7 additions & 7 deletions .github/workflows/static-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ on:

jobs:

psalm:
runs-on: 'ubuntu-20.04'
phpstan:
runs-on: 'ubuntu-22.04'
strategy:
matrix:
php:
- '8.1'
- '8.3'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
Expand All @@ -25,8 +25,8 @@ jobs:
- uses: 'ramsey/composer-install@v2'
with:
dependency-versions: 'highest'
# Require vimeo/psalm via command-line instead of adding to Composer's
# Require PHPStan via command-line instead of adding to Composer's
# "require-dev"; we only want to run static analysis once on the highest
# version of PHP available. Also, Psalm on 5.6? No, thank you.
- run: 'composer require --dev vimeo/psalm'
- run: './vendor/bin/psalm --config="tests/psalm.xml" --threads="$(nproc)" --php-version="5.6" --no-cache --stats --show-info=false --output-format="github"'
# version of PHP available.
- run: 'composer require --dev phpstan/phpstan phpstan/phpstan-deprecation-rules'
- run: './vendor/bin/phpstan analyze --no-progress --error-format="github"'
4 changes: 4 additions & 0 deletions .github/workflows/testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
- '7.4'
- '8.0'
- '8.1'
- '8.2'
- '8.3'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
Expand All @@ -44,6 +46,8 @@ jobs:
- '7.4'
- '8.0'
- '8.1'
- '8.2'
- '8.3'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
},
"require": {
"php-64bit": ">=5.6",
"php-ipv6": ">=5.6"
"php-ipv6": ">=5.6",
"ext-ctype": "*"
},
"autoload-dev": {
"psr-4": {
Expand All @@ -28,7 +29,7 @@
},
"require-dev": {
"ext-pdo": "*",
"doctrine/dbal": "^2.3",
"doctrine/dbal": "^2.3 || ^3",
"phpunit/phpunit": "*"
},
"prefer-stable": true,
Expand Down
17 changes: 17 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
parameters:
level: 'max'
paths: [ 'src', 'tests' ]
checkFunctionNameCase: true
checkGenericClassInNonGenericObjectType: true
reportUnmatchedIgnoredErrors: true
treatPhpDocTypesAsCertain: false
parallel:
maximumNumberOfProcesses: 4
ignoreErrors:
-
# This project purposefully uses variable constructors and "new static()".
message: "#^Unsafe usage of new static\\(\\)\\.$#"

includes:
- 'vendor/phpstan/phpstan-deprecation-rules/rules.neon'
- 'vendor/phpstan/phpstan/conf/bleedingEdge.neon'
4 changes: 1 addition & 3 deletions src/Doctrine/AbstractType.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
if (empty($value)) {
return null;
}
/** @var string|\Darsyn\IP\IpInterface $value */
if (\is_a($value, $this->getIpClass(), false)) {
if (\is_object($value) && \is_a($value, $this->getIpClass(), false)) {
/** @var \Darsyn\IP\IpInterface $value */
return $value;
}
/** @var string $value */
try {
return $this->createIpObject($value);
} catch (IpException $e) {
Expand Down
21 changes: 16 additions & 5 deletions src/Formatter/ConsistentFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function ntop($binary)
if (\is_string($binary)) {
$length = MbString::getLength($binary);
if ($length === 16) {
return $this->ntopVersion6(Binary::toHex($binary));
return $this->ntopVersion6($binary);
}
if ($length === 4) {
return $this->ntopVersion4($binary);
Expand All @@ -26,11 +26,12 @@ public function ntop($binary)
}

/**
* @param string $hex
* @param string $binary
* @return string
*/
private function ntopVersion6($hex)
private function ntopVersion6($binary)
{
$hex = Binary::toHex($binary);
$parts = \str_split($hex, 4);
$zeroes = \array_map(function ($part) {
return $part === '0000';
Expand All @@ -57,7 +58,10 @@ private function ntopVersion6($hex)
if ($maxLength > 0) {
\array_splice($parts, $startPosition, $maxLength, ':');
}
return \str_pad(\preg_replace('/\:{2,}/', '::', \implode(':', $parts)), 2, ':');
if (null === $shortened = \preg_replace('/\:{2,}/', '::', \implode(':', $parts))) {
throw new FormatException($binary);
}
return \str_pad($shortened, 2, ':');
}

/**
Expand All @@ -66,6 +70,13 @@ private function ntopVersion6($hex)
*/
private function ntopVersion4($binary)
{
return \inet_ntop(\pack('A4', $binary));
// $pack return type is `string|false` below PHP 8 and `string`
// above PHP 8.
$pack = \pack('A4', $binary);
/** @phpstan-ignore-next-line (@phpstan-ignore identical.alwaysFalse) */
if (false === $pack || false === $protocol = \inet_ntop($pack)) {
throw new FormatException($binary);
}
return $protocol;
}
}
19 changes: 16 additions & 3 deletions src/Formatter/NativeFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ public function ntop($binary)
if (\is_string($binary)) {
$length = MbString::getLength($binary);
if ($length === 16 || $length === 4) {
return \inet_ntop(\pack('A' . (string) $length, $binary));
$pack = \pack(\sprintf('A%d', $length), $binary);
// $pack return type is `string|false` below PHP 8 and `string`
// above PHP 8.
/** @phpstan-ignore-next-line (@phpstan-ignore identical.alwaysFalse) */
if (false === $pack || false === $protocol = \inet_ntop($pack)) {
throw new FormatException($binary);
}
return $protocol;
}
}
throw new FormatException($binary);
Expand All @@ -28,11 +35,17 @@ public function pton($binary)
{
if (\is_string($binary)) {
if (\filter_var($binary, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
$sequence = \unpack('a4', \inet_pton($binary));
$number = \inet_pton($binary);
if (false === $number || false === $sequence = \unpack('a4', $number)) {
throw new FormatException($binary);
}
return \current($sequence);
}
if (\filter_var($binary, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$sequence = \unpack('a16', \inet_pton($binary));
$number = \inet_pton($binary);
if (false === $number || false === $sequence = \unpack('a16', $number)) {
throw new FormatException($binary);
}
return \current($sequence);
}
$length = MbString::getLength($binary);
Expand Down
8 changes: 5 additions & 3 deletions src/Util/Binary.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public static function fromHex($hex)
public static function toHex($binary)
{
if (!\is_string($binary)) {
throw new \InvalidArgumentException('Cannot convert non-string to hexidecimal.');
throw new \InvalidArgumentException('Cannot convert non-string to hexadecimal.');
}
if (false === $data = \unpack('H*', $binary)) {
throw new \InvalidArgumentException('Unknown error converting string to hexadecimal.');
}
$data = \unpack('H*', $binary);
return \reset($data);
}

Expand Down Expand Up @@ -61,7 +63,7 @@ public static function toHumanReadable($binary)
}
$hex = static::toHex($binary);
return \implode('', \array_map(function ($character) {
return MbString::padString(\decbin(\hexdec($character)), 8, '0', \STR_PAD_LEFT);
return MbString::padString(\decbin((int) \hexdec($character)), 8, '0', \STR_PAD_LEFT);
}, \function_exists('mb_str_split') ? \mb_str_split($hex, 2, '8bit') : \str_split($hex, 2)));
}
}
2 changes: 2 additions & 0 deletions tests/DataProvider/Formatter/ConsistentFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class ConsistentFormatter
{
/** @return list<array{string, string}> */
public static function getValidBinarySequences()
{
return [
Expand Down Expand Up @@ -33,6 +34,7 @@ public static function getValidBinarySequences()
];
}

/** @return list<array{mixed}> */
public static function getInvalidBinarySequences()
{
return [
Expand Down
2 changes: 2 additions & 0 deletions tests/DataProvider/Formatter/NativeFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class NativeFormatter
{
/** @return list<array{string, string}> */
public static function getValidBinarySequences()
{
return [
Expand Down Expand Up @@ -32,6 +33,7 @@ public static function getValidBinarySequences()
];
}

/** @return list<array{mixed}> */
public static function getInvalidBinarySequences()
{
return [
Expand Down
21 changes: 21 additions & 0 deletions tests/DataProvider/IPv4.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class IPv4 implements IpDataProviderInterface
{
/** @return list<array{string, string, string}> */
public static function getValidBinarySequences()
{
return [
Expand All @@ -23,6 +24,7 @@ public static function getValidBinarySequences()
];
}

/** @return list<array{string, string, string}> */
public static function getValidProtocolIpAddresses()
{
return [
Expand All @@ -41,11 +43,13 @@ public static function getValidProtocolIpAddresses()
];
}

/** @return list<array{string, string, string}> */
public static function getValidIpAddresses()
{
return array_merge(self::getValidBinarySequences(), self::getValidProtocolIpAddresses());
}

/** @return list<array{mixed}> */
public static function getInvalidIpAddresses()
{
return [
Expand All @@ -67,6 +71,7 @@ public static function getInvalidIpAddresses()
];
}

/** @return list<array{int, string}> */
public static function getValidCidrValues()
{
return [
Expand All @@ -82,6 +87,7 @@ public static function getValidCidrValues()
];
}

/** @return list<array{mixed}> */
public static function getInvalidCidrValues()
{
return [
Expand All @@ -97,6 +103,7 @@ public static function getInvalidCidrValues()
];
}

/** @return list<array{string, int}> */
public static function getNetworkIpAddresses()
{
return [
Expand All @@ -109,6 +116,7 @@ public static function getNetworkIpAddresses()
];
}

/** @return list<array{string, int}> */
public static function getBroadcastIpAddresses()
{
return [
Expand All @@ -121,6 +129,7 @@ public static function getBroadcastIpAddresses()
];
}

/** @return list<array{string, string, int}> */
public static function getValidInRangeIpAddresses()
{
return [
Expand All @@ -131,6 +140,7 @@ public static function getValidInRangeIpAddresses()
];
}

/** @return list<array{string, string, int}> */
public static function getCommonCidrValues()
{
return [
Expand All @@ -153,56 +163,67 @@ public static function getCommonCidrValues()
];
}

/** @return list<array{string, bool}> */
public static function getLinkLocalIpAddresses()
{
return self::getCategoryOfIpAddresses(self::LINK_LOCAL);
}

/** @return list<array{string, bool}> */
public static function getLoopbackIpAddresses()
{
return self::getCategoryOfIpAddresses(self::LOOPBACK);
}

/** @return list<array{string, bool}> */
public static function getMulticastIpAddresses()
{
return self::getCategoryOfIpAddresses(self::MULTICAST);
}

/** @return list<array{string, bool}> */
public static function getPrivateUseIpAddresses()
{
return self::getCategoryOfIpAddresses(self::PRIVATE_USE);
}

/** @return list<array{string, bool}> */
public static function getUnspecifiedIpAddresses()
{
return self::getCategoryOfIpAddresses(self::UNSPECIFIED);
}

/** @return list<array{string, bool}> */
public static function getBenchmarkingIpAddresses()
{
return self::getCategoryOfIpAddresses(self::BENCHMARKING);
}

/** @return list<array{string, bool}> */
public static function getDocumentationIpAddresses()
{
return self::getCategoryOfIpAddresses(self::DOCUMENTATION);
}

/** @return list<array{string, bool}> */
public static function getPublicUseIpAddresses()
{
return self::getCategoryOfIpAddresses(self::PUBLIC_USE_V4);
}

/** @return list<array{string, bool}> */
public static function getIsBroadcastIpAddresses()
{
return self::getCategoryOfIpAddresses(self::BROADCAST);
}

/** @return list<array{string, bool}> */
public static function getSharedIpAddresses()
{
return self::getCategoryOfIpAddresses(self::SHARED);
}

/** @return list<array{string, bool}> */
public static function getFutureReservedIpAddresses()
{
return self::getCategoryOfIpAddresses(self::FUTURE_RESERVED);
Expand Down
Loading
Loading