Skip to content

Commit f6581fd

Browse files
committed
ResolvedDomain should handle domain with root label
1 parent 0a3902e commit f6581fd

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

src/DomainName.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,4 @@ public function clear(): self;
124124
* If $length is null it returns all elements from $offset to the end of the Domain.
125125
*/
126126
public function slice(int $offset, ?int $length = null): self;
127-
128-
129127
}

src/ResolvedDomain.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,21 @@
1010

1111
final class ResolvedDomain implements ResolvedDomainName
1212
{
13+
private readonly DomainName $domain;
1314
private readonly DomainName $secondLevelDomain;
1415
private readonly DomainName $registrableDomain;
1516
private readonly DomainName $subDomain;
17+
private readonly EffectiveTopLevelDomain $suffix;
1618

1719
/**
1820
* @throws CannotProcessHost
1921
*/
2022
private function __construct(
21-
private readonly DomainName $domain,
22-
private readonly EffectiveTopLevelDomain $suffix
23+
DomainName $domain,
24+
EffectiveTopLevelDomain $suffix
2325
) {
26+
$this->domain = $domain;
27+
$this->suffix = $suffix;
2428
[
2529
'registrableDomain' => $this->registrableDomain,
2630
'secondLevelDomain' => $this->secondLevelDomain,
@@ -195,8 +199,10 @@ public function withSuffix(DomainNameProvider|Host|Stringable|string|int|null $s
195199
$suffix = Suffix::fromUnknown($suffix);
196200
}
197201

202+
$newDomain = $this->domain->withoutRootLabel()->slice(count($this->suffix))->append($suffix);
203+
198204
return new self(
199-
$this->domain->slice(count($this->suffix))->append($suffix),
205+
$this->domain->isAbsolute() ? $newDomain->withRootLabel() : $newDomain,
200206
$suffix->normalize($this->domain)
201207
);
202208
}
@@ -211,6 +217,10 @@ public function withSubDomain(DomainNameProvider|Host|Stringable|string|int|null
211217
}
212218

213219
$subDomain = RegisteredName::fromIDNA2008($subDomain);
220+
if ('' === $subDomain->withoutRootLabel()->value()) {
221+
throw SyntaxError::dueToMalformedValue($subDomain->toString());
222+
}
223+
214224
if ($this->subDomain->value() === $subDomain->value()) {
215225
return $this;
216226
}

src/ResolvedDomainTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ public function testItCanChangeItsSuffix(
322322
public static function withPublicSuffixWorksProvider(): iterable
323323
{
324324
$baseDomain = ResolvedDomain::fromICANN('example.com', 1);
325+
$baseRootDomain = ResolvedDomain::fromICANN('example.com.', 1);
325326

326327
return [
327328
'simple update (1)' => [
@@ -332,6 +333,14 @@ public static function withPublicSuffixWorksProvider(): iterable
332333
'isICANN' => false,
333334
'isPrivate' => false,
334335
],
336+
'simple update with root-label (1)' => [
337+
'domain' => $baseRootDomain,
338+
'publicSuffix' => 'be',
339+
'expected' => 'be',
340+
'isKnown' => false,
341+
'isICANN' => false,
342+
'isPrivate' => false,
343+
],
335344
'simple update (2)' => [
336345
'domain' => $baseDomain,
337346
'publicSuffix' => Suffix::fromPrivate('github.io'),
@@ -340,6 +349,14 @@ public static function withPublicSuffixWorksProvider(): iterable
340349
'isICANN' => false,
341350
'isPrivate' => true,
342351
],
352+
'simple update with root-label (2)' => [
353+
'domain' => $baseRootDomain,
354+
'publicSuffix' => Suffix::fromPrivate('github.io'),
355+
'expected' => 'github.io',
356+
'isKnown' => true,
357+
'isICANN' => false,
358+
'isPrivate' => true,
359+
],
343360
'same public suffix but PSL info is changed' => [
344361
'domain' => $baseDomain,
345362
'publicSuffix' => Suffix::fromPrivate('com'),
@@ -348,6 +365,14 @@ public static function withPublicSuffixWorksProvider(): iterable
348365
'isICANN' => false,
349366
'isPrivate' => true,
350367
],
368+
'same public suffix but PSL info is changed with root domain' => [
369+
'domain' => $baseRootDomain,
370+
'publicSuffix' => Suffix::fromPrivate('com'),
371+
'expected' => 'com',
372+
'isKnown' => true,
373+
'isICANN' => false,
374+
'isPrivate' => true,
375+
],
351376
'same public suffix but PSL info does not changed' => [
352377
'domain' => $baseDomain,
353378
'publicSuffix' => Suffix::fromICANN('com'),
@@ -372,6 +397,14 @@ public static function withPublicSuffixWorksProvider(): iterable
372397
'isICANN' => true,
373398
'isPrivate' => false,
374399
],
400+
'simple update IDN (2) with root domains' => [
401+
'domain' => ResolvedDomain::fromICANN(Domain::fromIDNA2003('www.bébé.be.'), 1),
402+
'publicSuffix' => Suffix::fromICANN(Domain::fromIDNA2003('xn--p1ai')),
403+
'expected' => 'рф',
404+
'isKnown' => true,
405+
'isICANN' => true,
406+
'isPrivate' => false,
407+
],
375408
'adding the public suffix to a single label domain' => [
376409
'domain' => ResolvedDomain::fromUnknown('localhost'),
377410
'publicSuffix' => 'www',

0 commit comments

Comments
 (0)