‪TYPO3CMS  ‪main
UriValue.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\UriInterface;
23 
28 final class ‪UriValue extends ‪Uri implements \Stringable, ‪EqualityInterface, ‪CoveringInterface, ‪SourceInterface
29 {
30  private string ‪$domainName = '';
31  private bool ‪$entireWildcard = false;
32  private bool ‪$domainWildcard = false;
33 
34  public static function ‪fromUri(UriInterface $other): self
35  {
36  return new self((string)$other);
37  }
38 
39  public function ‪__toString(): string
40  {
41  if ($this->entireWildcard) {
42  return '*';
43  }
44  if ($this->domainName !== '') {
45  return ($this->domainWildcard ? '*.' : '') . ‪$this->domainName;
46  }
47  return parent::__toString();
48  }
49 
50  public function ‪equals(‪EqualityInterface $other): bool
51  {
52  return $other instanceof self && (string)$other === (string)$this;
53  }
54 
55  public function ‪covers(‪CoveringInterface $other): bool
56  {
57  if (!$other instanceof self) {
58  return false;
59  }
60  // `*` matches anything
61  if ($this->entireWildcard) {
62  return true;
63  }
64  // `*.example.com` or `example.com`
65  if ($this->domainName !== '') {
66  if ($this->domainWildcard) {
67  if (($other->domainName !== '' && str_ends_with($other->domainName, '.' . $this->domainName))
68  || ($other->host !== '' && str_ends_with($other->host, '.' . $this->domainName))
69  ) {
70  return true;
71  }
72  } else {
73  if (($other->domainName !== '' && $other->domainName === $this->domainName)
74  || ($other->host !== '' && $other->host === $this->domainName)
75  ) {
76  return true;
77  }
78  }
79  }
80  // `https://*.example.com`
81  if ($other->host !== ''
82  && $this->scheme === $other->scheme
83  && str_starts_with($this->host, '*.')
84  && str_ends_with($other->host, substr($this->host, 1))
85  ) {
86  return true;
87  }
88  return str_starts_with((string)$other, (string)$this);
89  }
90 
91  public function ‪getDomainName(): string
92  {
93  return ‪$this->domainName;
94  }
95 
96  protected function ‪parseUri(string $uri): void
97  {
98  if ($uri === '*') {
99  $this->entireWildcard = true;
100  return;
101  }
102  parent::parseUri($uri);
103  // ignore fragments per default
104  $this->fragment = '';
105  // handle domain names that were recognized as paths
106  if ($this->‪canBeParsedAsWildcardDomainName()) {
107  $this->domainName = substr($this->path, 4);
108  $this->domainWildcard = true;
109  } elseif ($this->‪canBeParsedAsDomainName()) {
110  $this->domainName = ‪$this->path;
111  }
112  }
113 
114  private function ‪canBeParsedAsDomainName(): bool
115  {
116  return $this->path !== ''
117  && $this->scheme === ''
118  && $this->host === ''
119  && $this->query === ''
120  && $this->userInfo === ''
121  && $this->‪validateDomainName($this->path);
122  }
123 
124  private function ‪canBeParsedAsWildcardDomainName(): bool
125  {
126  if ($this->path === ''
127  || $this->scheme !== ''
128  || $this->host !== ''
129  || $this->query !== ''
130  || $this->userInfo !== ''
131  || !str_starts_with($this->path, '%2A')
132  ) {
133  return false;
134  }
135  $possibleDomainName = substr($this->path, 4);
136  return $this->‪validateDomainName($possibleDomainName);
137  }
138 
139  private function ‪validateDomainName(string $value): bool
140  {
141  return filter_var($value, FILTER_VALIDATE_DOMAIN) !== false;
142  }
143 }
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\covers
‪covers(CoveringInterface $other)
Definition: UriValue.php:55
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\__toString
‪__toString()
Definition: UriValue.php:39
‪TYPO3\CMS\Core\Domain\EqualityInterface
Definition: EqualityInterface.php:26
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\validateDomainName
‪validateDomainName(string $value)
Definition: UriValue.php:139
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\$entireWildcard
‪bool $entireWildcard
Definition: UriValue.php:31
‪TYPO3\CMS\Core\Http\Uri\$path
‪string $path
Definition: Uri.php:83
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceInterface
Definition: SourceInterface.php:27
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:30
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\getDomainName
‪getDomainName()
Definition: UriValue.php:91
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\CoveringInterface
Definition: CoveringInterface.php:26
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\$domainName
‪string $domainName
Definition: UriValue.php:30
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\parseUri
‪parseUri(string $uri)
Definition: UriValue.php:96
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy
Definition: ConsumableNonce.php:18
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\equals
‪equals(EqualityInterface $other)
Definition: UriValue.php:50
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue
Definition: UriValue.php:29
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\canBeParsedAsDomainName
‪canBeParsedAsDomainName()
Definition: UriValue.php:114
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\canBeParsedAsWildcardDomainName
‪canBeParsedAsWildcardDomainName()
Definition: UriValue.php:124
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\$domainWildcard
‪bool $domainWildcard
Definition: UriValue.php:32
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\fromUri
‪static fromUri(UriInterface $other)
Definition: UriValue.php:34