MediaWiki REL1_31
LinkFilterTest.php
Go to the documentation of this file.
1<?php
2
4
10
11 protected function setUp() {
12 parent::setUp();
13
14 $this->setMwGlobals( 'wgUrlProtocols', [
15 'http://',
16 'https://',
17 'ftp://',
18 'irc://',
19 'ircs://',
20 'gopher://',
21 'telnet://',
22 'nntp://',
23 'worldwind://',
24 'mailto:',
25 'news:',
26 'svn://',
27 'git://',
28 'mms://',
29 '//',
30 ] );
31 }
32
41 function createRegexFromLIKE( $like ) {
42 $regex = '!^';
43
44 foreach ( $like as $item ) {
45 if ( $item instanceof LikeMatch ) {
46 if ( $item->toString() == '%' ) {
47 $regex .= '.*';
48 } elseif ( $item->toString() == '_' ) {
49 $regex .= '.';
50 }
51 } else {
52 $regex .= preg_quote( $item, '!' );
53 }
54
55 }
56
57 $regex .= '$!';
58
59 return $regex;
60 }
61
67 public static function provideValidPatterns() {
68 return [
69 // Protocol, Search pattern, URL which matches the pattern
70 [ 'http://', '*.test.com', 'http://www.test.com' ],
71 [ 'http://', 'test.com:8080/dir/file', 'http://name:pass@test.com:8080/dir/file' ],
72 [ 'https://', '*.com', 'https://s.s.test..com:88/dir/file?a=1&b=2' ],
73 [ 'https://', '*.com', 'https://name:pass@secure.com/index.html' ],
74 [ 'http://', 'name:pass@test.com', 'http://test.com' ],
75 [ 'http://', 'test.com', 'http://name:pass@test.com' ],
76 [ 'http://', '*.test.com', 'http://a.b.c.test.com/dir/dir/file?a=6' ],
77 [ null, 'http://*.test.com', 'http://www.test.com' ],
78 [ 'mailto:', 'name@mail.test123.com', 'mailto:name@mail.test123.com' ],
79 [ '',
80 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg',
81 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg'
82 ],
83 [ '', 'http://name:pass@*.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg',
84 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg' ],
85 [ '', 'http://name:wrongpass@*.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]',
86 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg' ],
87 [ 'http://', 'name:pass@*.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg',
88 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg' ],
89 [ '', 'http://name:pass@www.test.com:12345',
90 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg' ],
91 [ 'ftp://', 'user:pass@ftp.test.com:1233/home/user/file;type=efw',
92 'ftp://user:pass@ftp.test.com:1233/home/user/file;type=efw' ],
93 [ null, 'ftp://otheruser:otherpass@ftp.test.com:1233/home/user/file;type=',
94 'ftp://user:pass@ftp.test.com:1233/home/user/file;type=efw' ],
95 [ null, 'ftp://@ftp.test.com:1233/home/user/file;type=',
96 'ftp://user:pass@ftp.test.com:1233/home/user/file;type=efw' ],
97 [ null, 'ftp://ftp.test.com/',
98 'ftp://user:pass@ftp.test.com/home/user/file;type=efw' ],
99 [ null, 'ftp://ftp.test.com/',
100 'ftp://user:pass@ftp.test.com/home/user/file;type=efw' ],
101 [ null, 'ftp://*.test.com:222/',
102 'ftp://user:pass@ftp.test.com:222/home' ],
103 [ 'irc://', '*.myserver:6667/', 'irc://test.myserver:6667/' ],
104 [ 'irc://', 'name:pass@*.myserver/', 'irc://test.myserver:6667/' ],
105 [ 'irc://', 'name:pass@*.myserver/', 'irc://other:@test.myserver:6667/' ],
106 [ '', 'irc://test/name,string,abc?msg=t', 'irc://test/name,string,abc?msg=test' ],
107 [ '', 'https://gerrit.wikimedia.org/r/#/q/status:open,n,z',
108 'https://gerrit.wikimedia.org/r/#/q/status:open,n,z' ],
109 [ '', 'https://gerrit.wikimedia.org',
110 'https://gerrit.wikimedia.org/r/#/q/status:open,n,z' ],
111 [ 'mailto:', '*.test.com', 'mailto:name@pop3.test.com' ],
112 [ 'mailto:', 'test.com', 'mailto:name@test.com' ],
113 [ 'news:', 'test.1234afc@news.test.com', 'news:test.1234afc@news.test.com' ],
114 [ 'news:', '*.test.com', 'news:test.1234afc@news.test.com' ],
115 [ '', 'news:4df8kh$iagfewewf(at)newsbf02aaa.news.aol.com',
116 'news:4df8kh$iagfewewf(at)newsbf02aaa.news.aol.com' ],
117 [ '', 'news:*.aol.com',
118 'news:4df8kh$iagfewewf(at)newsbf02aaa.news.aol.com' ],
119 [ '', 'git://github.com/prwef/abc-def.git', 'git://github.com/prwef/abc-def.git' ],
120 [ 'git://', 'github.com/', 'git://github.com/prwef/abc-def.git' ],
121 [ 'git://', '*.github.com/', 'git://a.b.c.d.e.f.github.com/prwef/abc-def.git' ],
122 [ '', 'gopher://*.test.com/', 'gopher://gopher.test.com/0/v2/vstat' ],
123 [ 'telnet://', '*.test.com', 'telnet://shell.test.com/~home/' ],
124 [ '', 'http://test.com', 'http://test.com/index?arg=1' ],
125 [ 'http://', '*.test.com', 'http://www.test.com/index?arg=1' ],
126 [ '' ,
127 'http://xx23124:__ffdfdef__@www.test.com:12345/dir' ,
128 'http://name:pass@www.test.com:12345/dir/dir/file.xyz.php#__se__?arg1=_&arg2[]=4rtg'
129 ],
130
131 // Tests for false positives
132 [ 'http://', 'test.com', 'http://www.test.com', false ],
133 [ 'http://', 'www1.test.com', 'http://www.test.com', false ],
134 [ 'http://', '*.test.com', 'http://www.test.t.com', false ],
135 [ '', 'http://test.com:8080', 'http://www.test.com:8080', false ],
136 [ '', 'https://test.com', 'http://test.com', false ],
137 [ '', 'http://test.com', 'https://test.com', false ],
138 [ 'http://', 'http://test.com', 'http://test.com', false ],
139 [ null, 'http://www.test.com', 'http://www.test.com:80', false ],
140 [ null, 'http://www.test.com:80', 'http://www.test.com', false ],
141 [ null, 'http://*.test.com:80', 'http://www.test.com', false ],
142 [ '', 'https://gerrit.wikimedia.org/r/#/XXX/status:open,n,z',
143 'https://gerrit.wikimedia.org/r/#/q/status:open,n,z', false ],
144 [ '', 'https://*.wikimedia.org/r/#/q/status:open,n,z',
145 'https://gerrit.wikimedia.org/r/#/XXX/status:open,n,z', false ],
146 [ 'mailto:', '@test.com', '@abc.test.com', false ],
147 [ 'mailto:', 'mail@test.com', 'mail2@test.com', false ],
148 [ '', 'mailto:mail@test.com', 'mail2@test.com', false ],
149 [ '', 'mailto:@test.com', '@abc.test.com', false ],
150 [ 'ftp://', '*.co', 'ftp://www.co.uk', false ],
151 [ 'ftp://', '*.co', 'ftp://www.co.m', false ],
152 [ 'ftp://', '*.co/dir/', 'ftp://www.co/dir2/', false ],
153 [ 'ftp://', 'www.co/dir/', 'ftp://www.co/dir2/', false ],
154 [ 'ftp://', 'test.com/dir/', 'ftp://test.com/', false ],
155 [ '', 'http://test.com:8080/dir/', 'http://test.com:808/dir/', false ],
156 [ '', 'http://test.com/dir/index.html', 'http://test.com/dir/index.php', false ],
157
158 // These are false positives too and ideally shouldn't match, but that
159 // would require using regexes and RLIKE instead of LIKE
160 // [ null, 'http://*.test.com', 'http://www.test.com:80', false ],
161 // [ '', 'https://*.wikimedia.org/r/#/q/status:open,n,z',
162 // 'https://gerrit.wikimedia.org/XXX/r/#/q/status:open,n,z', false ],
163 ];
164 }
165
179 function testMakeLikeArrayWithValidPatterns( $protocol, $pattern, $url, $shouldBeFound = true ) {
180 $indexes = wfMakeUrlIndexes( $url );
181 $likeArray = LinkFilter::makeLikeArray( $pattern, $protocol );
182
183 $this->assertTrue( $likeArray !== false,
184 "LinkFilter::makeLikeArray('$pattern', '$protocol') returned false on a valid pattern"
185 );
186
187 $regex = $this->createRegexFromLIKE( $likeArray );
188 $debugmsg = "Regex: '" . $regex . "'\n";
189 $debugmsg .= count( $indexes ) . " index(es) created by wfMakeUrlIndexes():\n";
190
191 $matches = 0;
192
193 foreach ( $indexes as $index ) {
194 $matches += preg_match( $regex, $index );
195 $debugmsg .= "\t'$index'\n";
196 }
197
198 if ( $shouldBeFound ) {
199 $this->assertTrue(
200 $matches > 0,
201 "Search pattern '$protocol$pattern' does not find url '$url' \n$debugmsg"
202 );
203 } else {
204 $this->assertFalse(
205 $matches > 0,
206 "Search pattern '$protocol$pattern' should not find url '$url' \n$debugmsg"
207 );
208 }
209 }
210
216 public static function provideInvalidPatterns() {
217 return [
218 [ '' ],
219 [ '*' ],
220 [ 'http://*' ],
221 [ 'http://*/' ],
222 [ 'http://*/dir/file' ],
223 [ 'test.*.com' ],
224 [ 'http://test.*.com' ],
225 [ 'test.*.com' ],
226 [ 'http://*.test.*' ],
227 [ 'http://*test.com' ],
228 [ 'https://*' ],
229 [ '*://test.com' ],
230 [ 'mailto:name:pass@t*est.com' ],
231 [ 'http://*:888/' ],
232 [ '*http://' ],
233 [ 'test.com/*/index' ],
234 [ 'test.com/dir/index?arg=*' ],
235 ];
236 }
237
248 $this->assertFalse(
249 LinkFilter::makeLikeArray( $pattern ),
250 "'$pattern' is not a valid pattern and should be rejected"
251 );
252 }
253
254}
wfMakeUrlIndexes( $url)
Make URL indexes, appropriate for the el_index field of externallinks.
LinkFilter Database.
createRegexFromLIKE( $like)
createRegexFromLike($like)
static provideValidPatterns()
provideValidPatterns()
testMakeLikeArrayWithValidPatterns( $protocol, $pattern, $url, $shouldBeFound=true)
testMakeLikeArrayWithValidPatterns()
static provideInvalidPatterns()
provideInvalidPatterns()
testMakeLikeArrayWithInvalidPatterns( $pattern)
testMakeLikeArrayWithInvalidPatterns()
static makeLikeArray( $filterEntry, $protocol='http://')
Make an array to be used for calls to Database::buildLike(), which will match the specified string.
Base class that store and restore the Language objects.
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown.
Used by Database::buildLike() to represent characters that have special meaning in SQL LIKE clauses a...
Definition LikeMatch.php:10
processing should stop and the error should be shown to the user * false
Definition hooks.txt:187