Skip to content

Commit fa7937a

Browse files
authored
Merge pull request #215 from jeremykendall/develop
Prepare 5.2 release
2 parents 2f2c542 + 758dfa2 commit fa7937a

22 files changed

+776
-240
lines changed

.gitattributes

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
* text=auto
22

3-
/.editorconfig export-ignore
4-
/.gitattributes export-ignore
5-
/.github export-ignore
6-
/.gitignore export-ignore
7-
/.php_cs export-ignore
8-
/.travis.yml export-ignore
9-
/README.md export-ignore
10-
/CHANGELOG.md export-ignore
11-
/phpunit.xml.dist export-ignore
12-
/tests export-ignore
3+
/.editorconfig export-ignore
4+
/.gitattributes export-ignore
5+
/.github export-ignore
6+
/.gitignore export-ignore
7+
/.php_cs export-ignore
8+
/.phpstan.src.neon export-ignore
9+
/.phpstan.tests.neon export-ignore
10+
/.travis.yml export-ignore
11+
/README.md export-ignore
12+
/phpunit.xml.dist export-ignore
13+
/tests export-ignore

.travis.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ sudo: false
55
matrix:
66
include:
77
- php: 7.0
8-
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true IGNORE_PLATFORMS=false
8+
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=false
99
- php: 7.1
10-
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true IGNORE_PLATFORMS=false
10+
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=false
1111
- php: 7.2
12-
env: COLLECT_COVERAGE=false VALIDATE_CODING_STYLE=false IGNORE_PLATFORMS=true
12+
env: VALIDATE_CODING_STYLE=true RUN_PHPSTAN=true IGNORE_PLATFORMS=false
1313
- php: nightly
14-
env: COLLECT_COVERAGE=false VALIDATE_CODING_STYLE=false IGNORE_PLATFORMS=true
14+
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=true
1515
allow_failures:
1616
- php: nightly
1717
fast_finish: true
@@ -31,5 +31,5 @@ script:
3131
- composer phpunit
3232

3333
after_script:
34-
- if [ "$COLLECT_COVERAGE" == "true" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/clover.xml; fi
35-
- if [ "$VALIDATE_CODING_STYLE" == "true" ]; then composer phpcs; fi
34+
- if [ "$VALIDATE_CODING_STYLE" == "true" ]; then composer phpcs; fi
35+
- if [ "$RUN_PHPSTAN" == "true" ]; then composer phpstan; fi

CHANGELOG.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
# Changelog
22

3-
All Notable changes to `PHP Domain Parser` will be documented in this file
3+
All Notable changes to `PHP Domain Parser` **5.x** series will be documented in this file
4+
5+
## 5.2.0 - 2018-02-23
6+
7+
### Added
8+
9+
- `Pdp\Rules::getPublicSuffix` returns a `Pdp\PublicSuffix` value object
10+
- `Pdp\Rules::__set_state` is implemented
11+
- `Pdp\Domain::toUnicode` returns a `Pdp\Domain` with its value converted to its Unicode form
12+
- `Pdp\Domain::toAscii` returns a `Pdp\Domain` with its value converted to its AScii form
13+
- `Pdp\PublicSuffix::toUnicode` returns a `Pdp\PublicSuffix` with its value converted to its Unicode form
14+
- `Pdp\PublicSuffix::toAscii` returns a `Pdp\PublicSuffix` with its value converted to its AScii form
15+
16+
### Fixed
17+
18+
- `Pdp\Domain::getDomain` returns the normalized form of the domain name
19+
- `Pdp\PublicSuffix` is no longer internal.
20+
- Normalizes IDN conversion using a internal `IDNConverterTrait`
21+
- Internal code improved by requiring PHPStan for development
22+
23+
### Deprecated
24+
25+
- None
26+
27+
### Removed
28+
29+
- None
430

531
## 5.1.0 - 2017-12-18
632

README.md

Lines changed: 83 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ System Requirements
2828
You need:
2929

3030
- **PHP >= 7.0** but the latest stable version of PHP is recommended
31-
- the `mbstring` extension
3231
- the `intl` extension
3332

3433
Dependencies
@@ -48,27 +47,7 @@ Documentation
4847

4948
### Domain name resolution
5049

51-
In order to resolve a domain name one we must:
52-
53-
- Convert the Public Suffix List (PSL) into a structure usable in PHP
54-
- Resolve the domain name against the PSL rules
55-
56-
PSL Conversion is done using the `Pdp\Converter` class.
57-
58-
~~~php
59-
<?php
60-
61-
namespace Pdp;
62-
63-
final class Converter
64-
{
65-
public function convert(string $content): array
66-
}
67-
~~~
68-
69-
The `Pdp\Converter::convert` method expects the raw content of a PSL and returns its `array` representation.
70-
71-
Once the PSL has been converted we can used the returned `array` to instantiate a `Pdp\Rules` object which is responsable for resolving a given domain name.
50+
The `Pdp\Rules` object is responsible for domain name resolution.
7251

7352
~~~php
7453
<?php
@@ -84,21 +63,26 @@ final class Rules
8463
public static function createFromPath(string $path, $context = null): self
8564
public static function createFromString(string $content): self
8665
public function __construct(array $rules)
66+
public function getPublicSuffix(string $domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
8767
public function resolve(string $domain = null, string $section = self::ALL_DOMAINS): Domain
8868
}
8969
~~~
9070

91-
Starting with version 5.1.0, the following named constructors arre added to ease `Rules` instantiation.
71+
**NEW IN VERSION 5.2:**
9272

93-
- `Rules::createFromString` expects a string content which follows [the PSL format](https://publicsuffix.org/list/#list-format);
73+
- `Rules::getPublicSuffix` returns a `PublicSuffix` object determined from the `Rules` object;
74+
75+
**NEW IN VERSION 5.1:**
9476

77+
- `Rules::createFromString` expects a string content which follows [the PSL format](https://publicsuffix.org/list/#list-format);
9578
- `Rules::createFromPath` expects a valid path to a readable PSL. You can optionnally submit a context resource as defined in PHP's `fopen` function;
9679

9780
Both named constructors:
9881

9982
- uses internally a `Pdp\Converter` object to convert the raw content into a suitable array to instantiate a valid `Pdp\Rules`;
10083
- do not have any cache functionnality;
10184

85+
#### Usage
10286

10387
Domain name resolution is done using the `Pdp\Rules::resolve` method which expects at most two parameters:
10488

@@ -108,9 +92,7 @@ Domain name resolution is done using the `Pdp\Rules::resolve` method which expec
10892
- `Rules::ICANN_DOMAINS`, to validate against the PSL ICANN DOMAINS section only.
10993
- `Rules::PRIVATE_DOMAINS`, to validate against the PSL PRIVATE DOMAINS section only.
11094

111-
By default, the `$section` argument is equal to `Rules::ALL_DOMAINS`. If an unsupported section is submitted a `Pdp\Exception` exception will be thrown.
112-
113-
**WARNING: The `Pdp\Rules::resolve` does not validate the submitted host. You are require to use a host validator prior to using this library.**
95+
By default, the `$section` argument is equal to `Rules::ALL_DOMAINS`. If an unsupported section is submitted a `Pdp\Exception` exception will be thrown.
11496

11597
The `Pdp\Rules::resolve` returns a `Pdp\Domain` object.
11698

@@ -126,34 +108,29 @@ final class Domain implements JsonSerializable
126108
public function isKnown(): bool;
127109
public function isICANN(): bool;
128110
public function isPrivate(): bool;
111+
public function toUnicode(): self;
112+
public function toAscii(): self;
129113
}
130114
~~~
131115

132-
The `Pdp\Domain` getter methods returns:
133-
134-
- the submitted domain name using `Pdp\Domain::getDomain`
135-
- the public suffix part normalized according to the domain using `Pdp\Domain::getPublicSuffix`
136-
- the registrable domain part using `Pdp\Domain::getRegistrableDomain`
137-
- the subdomain part using `Pdp\Domain::getSubDomain`.
138-
139-
If the domain name or some of its part are seriously malformed or unrecognized, the getter methods will return `null`.
116+
**NEW IN VERSION 5.2:**
140117

141-
**The Domain name status depends on the PSL section used to resolve it:**
142-
143-
- `Pdp\Domain::isKnown` returns `true` if the public suffix is found in the selected PSL;
144-
- `Pdp\Domain::isICANN` returns `true` if the public suffix is found in a selected PSL which includes the ICANN DOMAINS section;
145-
- `Pdp\Domain::isPrivate` returns `true` if the public suffix is found in a selected PSL which includes the PRIVATE DOMAINS section;
118+
- `Domain::toUnicode` returns an instance with the domain converted to its unicode representation;
119+
- `Domain::toAscii` returns an instance with the domain converted to its ascii representation;
120+
- `Domain::getDomain` will lowercase the domain name to normalize its content;
146121

147-
**THIS EXAMPLE ILLUSTRATES HOW EACH OBJECT IS USED BUT SHOULD BE AVOID IN PRODUCTON**
122+
**THIS EXAMPLE ILLUSTRATES HOW THE OBJECT WORK BUT SHOULD BE AVOIDED IN PRODUCTON**
148123

149124
~~~php
150125
<?php
151126

152127
use Pdp\Rules;
128+
use Pdp\Converter;
153129

154-
$rules = Rules::createFromPath('https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat');
130+
$pdp_url = 'https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat';
131+
$rules = Rules::createFromPath($pdp_url);
155132

156-
$domain = $rules->resolve('www.ulb.ac.be'); //using Rules::ALL_DOMAINS
133+
$domain = $rules->resolve('www.Ulb.AC.be'); //using Rules::ALL_DOMAINS
157134
$domain->getDomain(); //returns 'www.ulb.ac.be'
158135
$domain->getPublicSuffix(); //returns 'ac.be'
159136
$domain->getRegistrableDomain(); //returns 'ulb.ac.be'
@@ -175,7 +152,7 @@ echo json_encode($domain, JSON_PRETTY_PRINT);
175152

176153
//The same domain will yield a different result using the PSL PRIVATE DOMAIN SECTION only
177154

178-
$domain = $rules->resolve('www.ulb.ac.be', Rules::PRIVATE_DOMAINS);
155+
$domain = $rules->resolve('www.Ulb.AC.be', Rules::PRIVATE_DOMAINS);
179156
echo json_encode($domain, JSON_PRETTY_PRINT);
180157
// returns
181158
// {
@@ -189,11 +166,49 @@ echo json_encode($domain, JSON_PRETTY_PRINT);
189166
// }
190167
~~~
191168

169+
The `Pdp\Domain` getter methods returns:
170+
171+
- the submitted domain name using `Pdp\Domain::getDomain`
172+
- the public suffix part normalized according to the domain using `Pdp\Domain::getPublicSuffix`
173+
- the registrable domain part using `Pdp\Domain::getRegistrableDomain`
174+
- the subdomain part using `Pdp\Domain::getSubDomain`.
175+
176+
If the domain name or some of its part are seriously malformed or unrecognized, the getter methods will return `null`.
177+
178+
**The Domain name status depends on the PSL section used to resolve it:**
179+
180+
- `Pdp\Domain::isKnown` returns `true` if the public suffix is found in the selected PSL;
181+
- `Pdp\Domain::isICANN` returns `true` if the public suffix is found using a PSL which includes the ICANN DOMAINS section;
182+
- `Pdp\Domain::isPrivate` returns `true` if the public suffix is found using a PSL which includes the PRIVATE DOMAINS section;
183+
184+
The `Rules::getPublicSuffix` method expects the same arguments as `Rules::resolve` but returns a `Pdp\PublicSuffix` object instead.
185+
186+
~~~php
187+
<?php
188+
189+
final class PublicSuffix implements Countable, JsonSerializable
190+
{
191+
public function getContent(): ?string
192+
public function isKnown(): bool;
193+
public function isICANN(): bool;
194+
public function isPrivate(): bool;
195+
public function toUnicode(): self;
196+
public function toAscii(): self;
197+
}
198+
~~~
199+
200+
While `Rules::resolve` will only throws an exception if the section value is invalid, the `Rules::getPublicSuffix` is more restrictive and will additionnally throw if:
201+
202+
- The domain name is invalid or seriously malformed
203+
- The public suffix can not be normalized and converted using the domain encoding.
204+
192205
**WARNING:**
193206

207+
**The `Pdp\Rules::resolve` does not validate the submitted host. You are require to use a host validator prior to using this library.**
208+
194209
**You should never use the library this way in production, without, at least, a caching mechanism to reduce PSL downloads.**
195210

196-
**Some people use the PSL to determine what is a valid domain name and what isn't. This is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace, if your software does not regularly receive PSL updates, it may erroneously think new gTLDs are not known. The DNS is the proper source for this information. If you must use it for this purpose, please do not bake static copies of the PSL into your software with no update mechanism.**
211+
**Using the PSL to determine what is a valid domain name and what isn't is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace. The DNS is the proper source for this information. If you must use this library for this purpose, please consider integrating a PSL update mechanism into your software.**
197212

198213
### Public Suffix List Maintenance
199214

@@ -221,8 +236,9 @@ To work as intended, the `Pdp\Manager` constructor requires:
221236

222237
- a [PSR-16](http://www.php-fig.org/psr/psr-16/) Cache object to store the rules locally.
223238

224-
- a `Pdp\HttpClient` object to retrieve the PSL.
225-
the `Pdp\HttpClient` is a simple interface which exposes the `HttpClient::getContent` method. This method expects a string URL representation has its sole argument and returns the body from the given URL resource as a string.
239+
- a `Pdp\HttpClient` object to retrieve the PSL.
240+
241+
The `Pdp\HttpClient` is a simple interface which exposes the `HttpClient::getContent` method. This method expects a string URL representation has its sole argument and returns the body from the given URL resource as a string.
226242
If an error occurs while retrieving such body a `HttpClientException` exception is thrown.
227243

228244
~~~php
@@ -411,6 +427,26 @@ Contributing
411427

412428
Contributions are welcome and will be fully credited. Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
413429

430+
Testing
431+
-------
432+
433+
`pdp-domain-parser` has:
434+
435+
- a [PHPUnit](https://phpunit.de) test suite
436+
- a coding style compliance test suite using [PHP CS Fixer](http://cs.sensiolabs.org/).
437+
- a code analysis compliance test suite using [PHPStan](https://github.com/phpstan/phpstan).
438+
439+
To run the tests, run the following command from the project folder.
440+
441+
``` bash
442+
$ composer test
443+
```
444+
445+
Security
446+
-------
447+
448+
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
449+
414450
Credits
415451
-------
416452

composer.json

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,13 @@
3939
"psr/simple-cache": "^1"
4040
},
4141
"require-dev": {
42-
"phpunit/phpunit": "^6.3",
42+
"composer/composer": "^1.6",
43+
"friendsofphp/php-cs-fixer": "^2.7",
4344
"mikey179/vfsStream": "^1.6",
44-
"friendsofphp/php-cs-fixer": "^2.7"
45+
"phpstan/phpstan": "^0.9.2",
46+
"phpstan/phpstan-phpunit": "^0.9.4",
47+
"phpstan/phpstan-strict-rules": "^0.9.0",
48+
"phpunit/phpunit": "^6.3"
4549
},
4650
"suggest": {
4751
"psr/simple-cache-implementation": "To enable using other cache providers",
@@ -59,11 +63,21 @@
5963
}
6064
},
6165
"scripts": {
66+
"phpcs": "php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes",
67+
"phpstan-src": "phpstan analyse -l 7 -c phpstan.src.neon src",
68+
"phpstan-tests": "phpstan analyse -l 7 -c phpstan.tests.neon tests",
69+
"phpstan": [
70+
"@phpstan-src",
71+
"@phpstan-tests"
72+
],
73+
"phpunit": "phpunit --coverage-text",
6274
"post-install-cmd": "\\Pdp\\Installer::updateLocalCache",
6375
"post-update-cmd": "\\Pdp\\Installer::updateLocalCache",
64-
"test": "phpunit --coverage-text; php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes",
65-
"phpunit": "phpunit --coverage-text",
66-
"phpcs": "php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes"
76+
"test": [
77+
"@phpunit",
78+
"@phpcs",
79+
"@phpstan"
80+
]
6781
},
6882
"extra": {
6983
"branch-alias": {

data/pdp-PSL-FULL-5a3cc7f81795bb2e48e848af42d287b4.cache

Lines changed: 0 additions & 1 deletion
This file was deleted.

data/pdp-PSL_FULL_5a3cc7f81795bb2e48e848af42d287b4.cache

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

phpstan.src.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
includes:
2+
- vendor/phpstan/phpstan-strict-rules/rules.neon
3+
parameters:
4+
ignoreErrors:
5+
- '#has invalid typehint type Psr\\SimpleCache\\DateInterval#'
6+
reportUnmatchedIgnoredErrors: false

phpstan.tests.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
includes:
2+
- vendor/phpstan/phpstan-strict-rules/rules.neon
3+
- vendor/phpstan/phpstan-phpunit/extension.neon
4+
- vendor/phpstan/phpstan-phpunit/rules.neon
5+
- vendor/phpstan/phpstan-phpunit/strictRules.neon

src/Converter.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
* Public Suffix List Parser.
1818
*
1919
* This class convert the Public Suffix List into an associative, multidimensional array
20+
*
21+
* @author Jeremy Kendall <[email protected]>
22+
* @author Ignace Nyamagana Butera <[email protected]>
2023
*/
2124
final class Converter
2225
{
26+
use IDNAConverterTrait;
27+
2328
/**
2429
* Convert the Public Suffix List into
2530
* an associative, multidimensional array
@@ -99,7 +104,7 @@ private function addRule(array $list, array $rule_parts): array
99104
// "The domain and all rules must be canonicalized in the normal way
100105
// for hostnames - lower-case, Punycode (RFC 3492)."
101106

102-
$part = idn_to_ascii($part, 0, INTL_IDNA_VARIANT_UTS46);
107+
$part = $this->idnToAscii($part);
103108
$isDomain = true;
104109
if (0 === strpos($part, '!')) {
105110
$part = substr($part, 1);

0 commit comments

Comments
 (0)