Test Setup Failed
Pull Request — latest (#3)
by Mark
33:50
created

ImageRenderer::isLinkPotentiallyUnsafe()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
11
 *  - (c) John MacFarlane
12
 *
13
 * For the full copyright and license information, please view the LICENSE
14
 * file that was distributed with this source code.
15
 */
16
17
namespace UnicornFail\Emoji\Renderer;
18
19
use League\Configuration\ConfigurationAwareInterface;
20
use League\Configuration\ConfigurationInterface;
21
use UnicornFail\Emoji\Node\Image;
22
use UnicornFail\Emoji\Node\Node;
23
use UnicornFail\Emoji\Util\HtmlElement;
24
25
final class ImageRenderer implements NodeRendererInterface, ConfigurationAwareInterface
26
{
27
    public const REGEX_UNSAFE_PROTOCOL    = '/^javascript:|vbscript:|file:|data:/i';
28
    public const REGEX_SAFE_DATA_PROTOCOL = '/^data:image\/(?:png|gif|jpeg|webp)/i';
29
30
    /**
31
     * @var ConfigurationInterface
32
     *
33
     * @psalm-readonly-allow-private-mutation
34
     * @psalm-suppress PropertyNotSetInConstructor
35
     */
36
    private $config;
37
38
    /**
39
     * @param Node $node
40
     *
41
     * {@inheritDoc}
42
     *
43
     * @psalm-suppress MoreSpecificImplementedParamType
44
     */
45
    public function render(Node $node)
46
    {
47
        if (! ($node instanceof Image)) {
48
            throw new \InvalidArgumentException('Incompatible node type: ' . \get_class($node));
49
        }
50
51
        $forbidUnsafeLinks = ! $this->config->get('allow_unsafe_links');
52
        if ($forbidUnsafeLinks && self::isLinkPotentiallyUnsafe($node->getUrl())) {
53
            $node->attributes->set('src', '');
54
        }
55
56
        return new HtmlElement('img', $node->attributes->export(), '', true);
57
    }
58
59
    public function setConfiguration(ConfigurationInterface $configuration): void
60
    {
61
        $this->config = $configuration;
62
    }
63
64
    /**
65
     * @psalm-pure
66
     */
67
    public static function isLinkPotentiallyUnsafe(string $url): bool
68
    {
69
        return \preg_match(self::REGEX_UNSAFE_PROTOCOL, $url) !== 0 && \preg_match(self::REGEX_SAFE_DATA_PROTOCOL, $url) === 0;
70
    }
71
}
72