Completed
Push — master ( f74955...cc059d )
by Josh
05:56 queued 13s
created

DisallowUnsafeDynamicURL   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 3
dl 0
loc 68
ccs 14
cts 14
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getNodes() 0 4 1
A isSafe() 0 4 1
A checkAttributeNode() 0 7 2
A checkElementNode() 0 7 2
A elementHasSafeUrl() 0 4 2
A isSafeUrl() 0 4 1
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2019 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\TemplateChecks;
9
10
use DOMAttr;
11
use DOMElement;
12
use DOMText;
13
use s9e\TextFormatter\Configurator\Helpers\TemplateHelper;
14
use s9e\TextFormatter\Configurator\Items\Attribute;
15
use s9e\TextFormatter\Configurator\Items\Tag;
16
17
/**
18
* This primary use of this check is to ensure that dynamic content cannot be used to create
19
* javascript: links
20
*/
21
class DisallowUnsafeDynamicURL extends AbstractDynamicContentCheck
22
{
23
	/**
24
	* @var string Regexp used to exclude nodes that start with a hardcoded scheme part, a hardcoded
25
	*             local part, or a fragment
26
	*/
27
	protected $safeUrlRegexp = '(^(?:(?!data|\\w*script)\\w+:|[^:]*/|#))i';
28
29
	/**
30
	* {@inheritdoc}
31
	*/
32 16
	protected function getNodes(DOMElement $template)
33
	{
34 16
		return TemplateHelper::getURLNodes($template->ownerDocument);
35
	}
36
37
	/**
38
	* {@inheritdoc}
39
	*/
40 8
	protected function isSafe(Attribute $attribute)
41
	{
42 8
		return $attribute->isSafeAsURL();
43
	}
44
45
	/**
46
	* {@inheritdoc}
47
	*/
48 8
	protected function checkAttributeNode(DOMAttr $attribute, Tag $tag)
49
	{
50 8
		if (!$this->isSafeUrl($attribute->value))
51
		{
52 8
			parent::checkAttributeNode($attribute, $tag);
53
		}
54
	}
55
56
	/**
57
	* {@inheritdoc}
58
	*/
59 6
	protected function checkElementNode(DOMElement $element, Tag $tag)
60
	{
61 6
		if (!$this->elementHasSafeUrl($element))
62
		{
63 6
			parent::checkElementNode($element, $tag);
64
		}
65
	}
66
67
	/**
68
	* Test whether given element contains a known-safe URL
69
	*
70
	* @param  DOMElement $element
71
	* @return bool
72
	*/
73 6
	protected function elementHasSafeUrl(DOMElement $element)
74
	{
75 6
		return $element->firstChild instanceof DOMText && $this->isSafeUrl($element->firstChild->textContent);
76
	}
77
78
	/**
79
	* Test whether given URL is known to be safe
80
	*
81
	* @param  string $url
82
	* @return bool
83
	*/
84 9
	protected function isSafeUrl($url)
85
	{
86 9
		return (bool) preg_match($this->safeUrlRegexp, $url);
87
	}
88
}