Skip to content

Commit e195ab7

Browse files
authored
Merge pull request #324 from jeremykendall/develop
Prepare 6.1.1 release
2 parents d8b196b + 1df0801 commit e195ab7

15 files changed

+2569
-954
lines changed

.github/workflows/build.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
php: [ '7.4', '8.0' ]
13+
php: [ '7.4', '8.0', '8.1' ]
1414
composer-flags: [ '' ]
1515
phpunit-flags: [ '--coverage-text' ]
1616
steps:
@@ -23,8 +23,8 @@ jobs:
2323
- run: composer update --no-progress ${{ matrix.composer-flags }}
2424
- run: composer phpunit
2525
- run: composer phpstan
26-
if: ${{ matrix.php == '8.0' }}
26+
if: ${{ matrix.php == '8.1' }}
2727
- run: composer psalm
28-
if: ${{ matrix.php == '8.0' }}
28+
if: ${{ matrix.php == '8.1' }}
2929
- run: composer phpcs
30-
if: ${{ matrix.php == '8.0' }}
30+
if: ${{ matrix.php == '8.1' }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ docs
44
build
55
.idea
66
.php_cs.cache
7+
.php-cs-fixer.cache
78
.phpunit.result.cache
89
composer.lock

.php-cs-fixer.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,31 @@
1111
'@PSR2' => true,
1212
'array_syntax' => ['syntax' => 'short'],
1313
'concat_space' => ['spacing' => 'none'],
14+
'global_namespace_import' => [
15+
'import_classes' => true,
16+
'import_constants' => true,
17+
'import_functions' => true,
18+
],
19+
'list_syntax' => ['syntax' => 'short'],
1420
'new_with_braces' => true,
1521
'no_blank_lines_after_phpdoc' => true,
1622
'no_empty_phpdoc' => true,
1723
'no_empty_comment' => true,
1824
'no_leading_import_slash' => true,
19-
'no_superfluous_phpdoc_tags' => true,
25+
'no_superfluous_phpdoc_tags' => [
26+
'allow_mixed' => true,
27+
'remove_inheritdoc' => true,
28+
'allow_unused_params' => false,
29+
],
2030
'no_trailing_comma_in_singleline_array' => true,
2131
'no_unused_imports' => true,
2232
'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'],
23-
'phpdoc_add_missing_param_annotation' => ['only_untyped' => false],
33+
'phpdoc_add_missing_param_annotation' => ['only_untyped' => true],
2434
'phpdoc_align' => true,
2535
'phpdoc_no_empty_return' => true,
2636
'phpdoc_order' => true,
2737
'phpdoc_scalar' => true,
28-
'phpdoc_to_comment' => false,
38+
'phpdoc_to_comment' => true,
2939
'phpdoc_summary' => true,
3040
'psr_autoloading' => true,
3141
'return_type_declaration' => ['space_before' => 'none'],
@@ -36,7 +46,5 @@
3646
'trailing_comma_in_multiline' => true,
3747
'trim_array_spaces' => true,
3848
'whitespace_after_comma_in_array' => true,
39-
'yoda_style' => true,
4049
])
41-
->setFinder($finder)
42-
;
50+
->setFinder($finder);

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,24 @@
22

33
All Notable changes to `PHP Domain Parser` starting from the **5.x** series will be documented in this file
44

5+
## 6.1.1 - 2022-02-18
6+
7+
### Added
8+
9+
- None
10+
11+
### Fixed
12+
13+
- [#321](https://github.com/jeremykendall/php-domain-parser/issues/321) improve resolving private domain suffix. `Rules::getPrivateDomain` will now throw if the domain name does not contain a "private" TLD.
14+
15+
### Deprecated
16+
17+
- None
18+
19+
### Removed
20+
21+
- None
22+
523
## 6.1.0 - 2021-06-19
624

725
### Added

composer.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@
4646
"ext-json": "*"
4747
},
4848
"require-dev": {
49-
"friendsofphp/php-cs-fixer": "^2.16",
49+
"friendsofphp/php-cs-fixer": "^v3.5.0",
5050
"guzzlehttp/guzzle": "^7.0",
51-
"guzzlehttp/psr7": "^1.6",
52-
"phpstan/phpstan": "^0.12",
53-
"phpstan/phpstan-phpunit": "^0.12",
54-
"phpstan/phpstan-strict-rules": "^0.12",
55-
"phpunit/phpunit": "^9.3",
56-
"psalm/plugin-phpunit": "^0.15.0",
51+
"guzzlehttp/psr7": "^1.6||^2.0",
52+
"phpstan/phpstan": "^1.4.6.",
53+
"phpstan/phpstan-phpunit": "^1.0.0",
54+
"phpstan/phpstan-strict-rules": "^1.1.0",
55+
"phpunit/phpunit": "^9.5.13",
56+
"psalm/plugin-phpunit": "^0.15.2",
5757
"psr/http-factory": "^1.0",
5858
"psr/simple-cache": "^1.0",
5959
"symfony/cache": "^v5.0",
60-
"vimeo/psalm": "^4.3"
60+
"vimeo/psalm": "^4.20"
6161
},
6262
"suggest": {
6363
"psr/http-client-implementation": "To use the storage functionnality which depends on PSR-18",

phpstan.neon

+8
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@ includes:
44
- vendor/phpstan/phpstan-phpunit/rules.neon
55
parameters:
66
ignoreErrors:
7+
- message: '#has no value type specified in iterable type array.#'
8+
path: src/Rules.php
9+
- message: '#has parameter \$(properties|rules|list|tmpList) with no value type specified in iterable type array.#'
10+
path: src/Rules.php
11+
- message: "#Cannot access offset '!' on mixed.#"
12+
path: src/Rules.php
13+
- message: '#Variable \$line on left side of \?\? always exists and is not nullable.#'
14+
path: src/Rules.php
715
reportUnmatchedIgnoredErrors: true

src/DomainName.php

-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ public function withLabel(int $key, $label): self;
101101
* If $key is non-negative, the removed label will be the label at $key position from the start.
102102
* If $key is negative, the removed label will be the label at $key position from the end.
103103
*
104-
* @param int ...$keys
105104
*
106105
* @throws CannotProcessHost If the key is out of bounds
107106
*/

src/DomainTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Pdp;
66

77
use PHPUnit\Framework\TestCase;
8+
use stdClass;
89
use TypeError;
910

1011
/**
@@ -314,7 +315,7 @@ public function withLabelWorksProvider(): iterable
314315
public function testWithLabelFailsWithTypeError(): void
315316
{
316317
$this->expectException(TypeError::class);
317-
Domain::fromIDNA2008('example.com')->withLabel(1, new \stdClass());
318+
Domain::fromIDNA2008('example.com')->withLabel(1, new stdClass());
318319
}
319320

320321
public function testWithLabelFailsWithInvalidKey(): void

src/Idna.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public static function toAscii(string $domain, int $options): IdnaInfo
9999

100100
self::supportsIdna();
101101

102-
/** @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
102+
/* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
103103
idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
104104

105105
/** @var array{result:string, isTransitionalDifferent:bool, errors:int} $idnaInfo */
@@ -124,7 +124,7 @@ public static function toUnicode(string $domain, int $options): IdnaInfo
124124

125125
self::supportsIdna();
126126

127-
/** @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
127+
/* @param-out array{errors: int, isTransitionalDifferent: bool, result: string} $idnaInfo */
128128
idn_to_utf8($domain, $options, INTL_IDNA_VARIANT_UTS46, $idnaInfo);
129129

130130
/** @var array{result:string, isTransitionalDifferent:bool, errors:int} $idnaInfo */

src/Rules.php

+12-7
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ final class Rules implements PublicSuffixList
3636
/**
3737
* PSL rules as a multidimensional associative array.
3838
*
39-
* @var array<string, array<array>>
39+
* @var array{ICANN_DOMAINS: array<array>, PRIVATE_DOMAINS: array<array>}
4040
*/
4141
private array $rules;
4242

4343
/**
44-
* @param array<string, array<array>> $rules
44+
* @param array{ICANN_DOMAINS: array<array>, PRIVATE_DOMAINS: array<array>} $rules
4545
*/
4646
private function __construct(array $rules)
4747
{
@@ -84,7 +84,7 @@ public static function fromString($content): self
8484
/**
8585
* Convert the Public Suffix List into an associative, multidimensional array.
8686
*
87-
* @return array<string, array<array>>
87+
* @return array{ICANN_DOMAINS: array<array>, PRIVATE_DOMAINS: array<array>}
8888
*/
8989
private static function parse(string $content): array
9090
{
@@ -165,7 +165,7 @@ private static function addRule(array $list, array $ruleParts): array
165165
}
166166

167167
/**
168-
* @param array{rules:array<string, array<array>>} $properties
168+
* @param array{rules:array{ICANN_DOMAINS: array<array>, PRIVATE_DOMAINS: array<array>}} $properties
169169
*/
170170
public static function __set_state(array $properties): self
171171
{
@@ -290,18 +290,23 @@ private function getPublicSuffixLengthFromSection(DomainName $domain, string $se
290290
$labelCount = 0;
291291
foreach ($domain->toAscii() as $label) {
292292
//match exception rule
293-
if (isset($rules[$label], $rules[$label]['!'])) {
293+
if (isset($rules[$label]['!'])) {
294294
break;
295295
}
296296

297297
//match wildcard rule
298-
if (isset($rules['*'])) {
298+
if (array_key_exists('*', $rules)) {
299299
++$labelCount;
300300
break;
301301
}
302302

303303
//no match found
304-
if (!isset($rules[$label])) {
304+
if (!array_key_exists($label, $rules)) {
305+
// for private domain suffix MUST be fully matched else no suffix is found
306+
// https://github.com/jeremykendall/php-domain-parser/issues/321
307+
if (self::PRIVATE_DOMAINS === $section && [] !== $rules) {
308+
$labelCount = 0;
309+
}
305310
break;
306311
}
307312

src/RulesTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -593,4 +593,22 @@ public function effectiveTLDProvider(): iterable
593593
],
594594
];
595595
}
596+
597+
public function testIssue321Success(): void
598+
{
599+
$result = self::$rules->resolve('node857-gelofesta.users.scale.virtualcloud.com.br');
600+
self::assertSame('users.scale.virtualcloud.com.br', $result->suffix()->value());
601+
self::assertTrue($result->suffix()->isPrivate());
602+
603+
$result = self::$rules->resolve('clientportal.virtualcloud.com.br');
604+
self::assertSame('com.br', $result->suffix()->value());
605+
self::assertTrue($result->suffix()->isICANN());
606+
}
607+
608+
public function testIssue321Failure(): void
609+
{
610+
$this->expectException(UnableToResolveDomain::class);
611+
612+
self::$rules->getPrivateDomain('clientportal.virtualcloud.com.br');
613+
}
596614
}

src/Storage/PublicSuffixListPsr16CacheTest.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Pdp\Storage;
66

7+
use DateInterval;
8+
use DateTimeImmutable;
79
use InvalidArgumentException;
810
use Pdp\Rules;
911
use PHPUnit\Framework\TestCase;
@@ -54,7 +56,7 @@ public function testItReturnsNullIfTheCacheContentCannotBeConvertedToTheCorrectI
5456
$cache = $this->createStub(CacheInterface::class);
5557
$cache->method('get')->willReturn('{"foo":"bar"}');
5658

57-
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new \DateTimeImmutable('+1 DAY'));
59+
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new DateTimeImmutable('+1 DAY'));
5860

5961
self::assertNull($pslCache->fetch('http://www.example.com'));
6062
}
@@ -65,7 +67,7 @@ public function testItCanStoreAPublicSuffixListInstance(): void
6567
$cache->method('set')->willReturn(true);
6668

6769
$psl = Rules::fromPath(dirname(__DIR__, 2).'/test_data/public_suffix_list.dat');
68-
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new \DateInterval('P1D'));
70+
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new DateInterval('P1D'));
6971

7072
self::assertTrue($pslCache->remember('http://www.example.com', $psl));
7173
}
@@ -76,7 +78,7 @@ public function testItReturnsFalseIfItCantStoreAPublicSuffixListInstance(): void
7678
$cache->method('set')->willReturn(false);
7779

7880
$psl = Rules::fromPath(dirname(__DIR__, 2).'/test_data/public_suffix_list.dat');
79-
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new \DateInterval('P1D'));
81+
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new DateInterval('P1D'));
8082

8183
self::assertFalse($pslCache->remember('http://www.example.com', $psl));
8284
}
@@ -89,7 +91,7 @@ public function testItReturnsFalseIfItCantCacheAPublicSuffixListInstance(): void
8991
$cache->method('set')->will(self::throwException($exception));
9092

9193
$psl = Rules::fromPath(dirname(__DIR__, 2).'/test_data/public_suffix_list.dat');
92-
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new \DateInterval('P1D'));
94+
$pslCache = new PublicSuffixListPsr16Cache($cache, 'pdp_', new DateInterval('P1D'));
9395

9496
self::assertFalse($pslCache->remember('http://www.example.com', $psl));
9597
}
@@ -120,7 +122,7 @@ public function testItCanDeleteTheCachedDatabase(): void
120122
$cache = $this->createStub(CacheInterface::class);
121123
$cache->method('delete')->willReturn(true);
122124

123-
$instance = new PublicSuffixListPsr16Cache($cache, 'pdp_', new \DateInterval('P1D'));
125+
$instance = new PublicSuffixListPsr16Cache($cache, 'pdp_', new DateInterval('P1D'));
124126
self::assertTrue($instance->forget($uri));
125127
}
126128

src/TopLevelDomainList.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ public function version(): string;
2424
*/
2525
public function lastUpdated(): DateTimeImmutable;
2626

27-
/**
28-
* {@inheritdoc}
29-
*/
27+
3028
public function count(): int;
3129

3230
/**

src/TopLevelDomainsTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public function testGetTopLevelDomain($tld): void
193193
}
194194

195195
/**
196-
* @return iterable<string,array>
196+
* @return iterable<string,array<object|string>>
197197
*/
198198
public function validDomainProvider(): iterable
199199
{
@@ -286,7 +286,7 @@ public function testGetTopLevelDomainWithUnregisteredTLD(): void
286286
}
287287

288288
/**
289-
* @return iterable<string,array>
289+
* @return iterable<string,array<string|object>>
290290
*/
291291
public function validTldProvider(): iterable
292292
{
@@ -312,7 +312,7 @@ public function __toString(): string
312312
}
313313

314314
/**
315-
* @return iterable<string,array>
315+
* @return iterable<string,array<object|string|null>>
316316
*/
317317
public function invalidTldProvider(): iterable
318318
{

0 commit comments

Comments
 (0)