Completed
Push — master ( cf38d9...2ecc50 )
by Rob
01:50
created

JavaScript   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 79.49%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 1
dl 0
loc 147
ccs 62
cts 78
cp 0.7949
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B removeDisallowedJavascript() 0 67 8
A jsLinkRemovalCallback() 0 4 1
A jsSrcRemovalCallback() 0 4 1
A naughtyJavascript() 0 9 1
C jsRemovalCallback() 0 53 12
1
<?php
2
3
namespace devtoolboxuk\soteria\voku\Resources;
4
5
class JavaScript extends Resources
0 ignored issues
show
Coding Style introduced by
The property $ANTI_XSS_STYLE is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
6
{
7
    private $ANTI_XSS_STYLE = 'anti-xss::STYLE';
8
9 6
    public function removeDisallowedJavascript($str)
0 ignored issues
show
Complexity introduced by
This operation has 65 execution paths which exceeds the configured maximum of 10.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
10
    {
11
        do {
12 6
            $original = $str;
13
14 6
            if (stripos($str, '<a') !== false) {
15 6
                $str = (string)preg_replace_callback(
16 6
                    '#<a[^a-z0-9>]+([^>]*?)(?:>|$)#i',
17
                    function ($matches) {
18 6
                        return $this->jsLinkRemovalCallback($matches);
19 6
                    },
20 6
                    $str
21
                );
22
            }
23
24 6
            if (stripos($str, '<img') !== false) {
25 6
                $str = (string)preg_replace_callback(
26 6
                    '#<img[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#i',
27
                    function ($matches) {
28 6
                        return $this->jsSrcRemovalCallback($matches);
29 6
                    },
30 6
                    $str
31
                );
32
            }
33
34 6
            if (stripos($str, '<audio') !== false) {
35
                $str = (string)preg_replace_callback(
36
                    '#<audio[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#i',
37
                    function ($matches) {
38
                        return $this->jsSrcRemovalCallback($matches);
39
                    },
40
                    $str
41
                );
42
            }
43
44 6
            if (stripos($str, '<video') !== false) {
45
                $str = (string)preg_replace_callback(
46
                    '#<video[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#i',
47
                    function ($matches) {
48
                        return $this->jsSrcRemovalCallback($matches);
49
                    },
50
                    $str
51
                );
52
            }
53
54 6
            if (stripos($str, '<source') !== false) {
55
                $str = (string)preg_replace_callback(
56
                    '#<source[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#i',
57
                    function ($matches) {
58
                        return $this->jsSrcRemovalCallback($matches);
59
                    },
60
                    $str
61
                );
62
            }
63
64 6
            if (stripos($str, 'script') !== false) {
65
                // US-ASCII: ¼ === <
66 6
                $str = (string)preg_replace(
67 6
                    '#(?:¼|<)/*(?:script).*(?:¾|>)#isuU',
68 6
                    $this->_replacement,
69 6
                    $str
70
                );
71
            }
72 6
        } while ($original !== $str);
73
74 6
        return (string)$str;
75
    }
76
77 6
    private function jsLinkRemovalCallback(array $match)
78
    {
79 6
        return $this->jsRemovalCallback($match, 'href');
80
    }
81
82 6
    private function jsRemovalCallback(array $match, $search)
0 ignored issues
show
Complexity introduced by
This operation has 240 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
Coding Style Naming introduced by
The variable $match_style_matched is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Naming introduced by
The variable $match_style is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
83
    {
84 6
        if (!$match[0]) {
85
            return '';
86
        }
87
88
        // init
89 6
        $match_style_matched = false;
90 6
        $match_style = [];
91
92
        // hack for style attributes v1
93 6
        if ($search === 'href' && stripos($match[0], 'style') !== false) {
94 2
            preg_match('/style=".*?"/i', $match[0], $match_style);
95 2
            $match_style_matched = (count($match_style) > 0);
96 2
            if ($match_style_matched) {
97 2
                $match[0] = str_replace($match_style[0], $this->ANTI_XSS_STYLE, $match[0]);
98
            }
99
        }
100
101 6
        $replacer = $this->_filter_attributes(str_replace(['<', '>'], '', $match[1]));
102
103
        // filter for "(.*)" but only in the "$search"-attribute
104 6
        if (stripos($replacer, $search) !== false) {
105 6
            $pattern = '#' . $search . '=(?<wrapper>(?:\'|\047)|(?:"|\042)).*(?:\g{wrapper})#isU';
106 6
            $matchInner = [];
107 6
            $foundSomethingBad = false;
108 6
            preg_match($pattern, $match[1], $matchInner);
109 6
            if (count($matchInner) > 0 && preg_match('#(?:\(.*([^\)]*?)(?:\)))#s', $matchInner[0])) {
110 6
                $foundSomethingBad = true;
111
112 6
                $replacer = (string)preg_replace($pattern, $search . '="' . $this->_replacement . '"', $replacer);
113
            }
114
115 6
            if (!$foundSomethingBad) {
116
                // filter for javascript
117 6
                $pattern = '#' . $search . '=.*(?:javascript:|view-source:|livescript:|wscript:|vbscript:|mocha:|charset=|window\.|\(?document\)?\.|\.cookie|<script|d\s*a\s*t\s*a\s*:)#ius';
118 6
                $matchInner = [];
119 6
                preg_match($pattern, $match[1], $matchInner);
120 6
                if (count($matchInner) > 0) {
121 2
                    $replacer = (string)preg_replace($pattern, $search . '="' . $this->_replacement . '"', $replacer);
122
                }
123
            }
124
        }
125
126 6
        $return = str_ireplace($match[1], $replacer, (string)$match[0]);
127
128
        // hack for style attributes v2
129 6
        if ($match_style_matched && $search === 'href') {
130 2
            $return = str_replace($this->ANTI_XSS_STYLE, $match_style[0], $return);
131
        }
132
133 6
        return $return;
134
    }
135
136 6
    private function jsSrcRemovalCallback(array $match)
137
    {
138 6
        return $this->jsRemovalCallback($match, 'src');
139
    }
140
141 6
    public function naughtyJavascript($str)
142
    {
143 6
        $str = (string) preg_replace(
144 6
            '#(alert|eval|prompt|confirm|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*)\)#uisU',
145 6
            '\\1\\2&#40;\\3&#41;',
146 6
            $str
147
        );
148 6
        return (string)$str;
149
    }
150
151
}