This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Net_URL2, a class representing a URL as per RFC 3986. |
||
4 | * |
||
5 | * PHP version 5 |
||
6 | * |
||
7 | * @category Networking |
||
8 | * @package Net_URL2 |
||
9 | * @author Some Pear Developers <[email protected]> |
||
10 | * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause |
||
11 | * @link https://tools.ietf.org/html/rfc3986 |
||
12 | */ |
||
13 | |||
14 | /** |
||
15 | * Test class for Net_URL2. |
||
16 | * |
||
17 | * @category Networking |
||
18 | * @package Net_URL2 |
||
19 | * @author Some Pear Developers <[email protected]> |
||
20 | * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause |
||
21 | * @version Release: @package_version@ |
||
22 | * @link https://pear.php.net/package/Net_URL2 |
||
23 | */ |
||
24 | class Net_URL2Test extends PHPUnit_Framework_TestCase |
||
25 | { |
||
26 | /** |
||
27 | * Tests setting a zero-length string and false as authority |
||
28 | * Also: Regression test for Bug #20420 |
||
29 | * |
||
30 | * @covers Net_URL2::setAuthority |
||
31 | * @return void |
||
32 | * @link https://pear.php.net/bugs/bug.php?id=20420 |
||
33 | */ |
||
34 | public function testSetEmptyAuthority() |
||
35 | { |
||
36 | $url = new Net_URL2('http://www.example.com/'); |
||
37 | $url->setAuthority(''); |
||
38 | $this->assertSame('', $url->getAuthority()); |
||
39 | $this->assertSame('', $url->getHost()); |
||
40 | $this->assertSame(false, $url->getPort()); |
||
41 | $this->assertSame(false, $url->getUserinfo()); |
||
42 | $this->assertSame(false, $url->getUser()); |
||
43 | |||
44 | $url->setAuthority(false); |
||
45 | $this->assertSame(false, $url->getAuthority()); |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * Tests setting an empty userinfo part |
||
50 | * Also: Regression test for Bug #20013 and Bug #20399 |
||
51 | * |
||
52 | * @covers Net_URL2::setUserinfo |
||
53 | * @covers Net_URL2::getUserinfo |
||
54 | * @covers Net_URL2::getURL |
||
55 | * @return void |
||
56 | * @link https://pear.php.net/bugs/bug.php?id=20013 |
||
57 | * @link https://pear.php.net/bugs/bug.php?id=20399 |
||
58 | */ |
||
59 | public function testSetEmptyUserinfo() |
||
60 | { |
||
61 | $url = new Net_URL2('http://@www.example.com/'); |
||
62 | $this->assertSame('http://www.example.com/', $url->getURL()); |
||
63 | |||
64 | $url = new Net_URL2('http://www.example.com/'); |
||
65 | $this->assertSame('http://www.example.com/', $url->getURL()); |
||
66 | $url->setUserinfo(''); |
||
67 | $this->assertSame('http://www.example.com/', $url->getURL()); |
||
68 | $this->assertSame('', $url->getUserinfo()); |
||
69 | $url->setUserinfo(false); |
||
70 | $this->assertSame('http://www.example.com/', $url->getURL()); |
||
71 | $this->assertFalse($url->getUserinfo()); |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * Tests an URL with no userinfo and normalization |
||
76 | * |
||
77 | * Also: Regression test for Bug #20385 |
||
78 | * |
||
79 | * @covers Net_URL2::getUserinfo |
||
80 | * @covers Net_URL2::normalize |
||
81 | * @covers Net_URL2::getNormalizedURL |
||
82 | * @return void |
||
83 | * @link https://pear.php.net/bugs/bug.php?id=20385 |
||
84 | */ |
||
85 | public function testNoUserinfoAndNormalize() |
||
86 | { |
||
87 | $testUrl = 'http://www.example.com/'; |
||
88 | |||
89 | $url = new Net_URL2($testUrl); |
||
90 | $this->assertFalse($url->getUserinfo()); |
||
91 | |||
92 | $url->normalize(); |
||
93 | $this->assertFalse($url->getUserinfo()); |
||
94 | |||
95 | $this->assertEquals($testUrl, $url->getURL()); |
||
96 | $this->assertEquals($testUrl, $url->getNormalizedURL()); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Tests setQueryVariable(). |
||
101 | * |
||
102 | * @return void |
||
103 | */ |
||
104 | public function testSetQueryVariable() |
||
105 | { |
||
106 | |||
107 | $url = new Net_URL2('http://www.example.com/'); |
||
108 | $url->setQueryVariable('pear', 'fun'); |
||
109 | $this->assertEquals($url->getURL(), 'http://www.example.com/?pear=fun'); |
||
110 | } |
||
111 | |||
112 | /** |
||
113 | * Tests setQueryVariables(). |
||
114 | * |
||
115 | * @return void |
||
116 | */ |
||
117 | public function testSetQueryVariables() |
||
118 | { |
||
119 | |||
120 | $url = new Net_URL2('http://www.example.com/'); |
||
121 | $url->setQueryVariables(array('pear' => 'fun')); |
||
122 | $this->assertEquals('http://www.example.com/?pear=fun', $url->getURL()); |
||
123 | $url->setQueryVariables(array('pear' => 'fun for sure')); |
||
124 | $this->assertEquals( |
||
125 | 'http://www.example.com/?pear=fun%20for%20sure', $url->getURL() |
||
126 | ); |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Tests unsetQueryVariable() |
||
131 | * |
||
132 | * @return void |
||
133 | */ |
||
134 | public function testUnsetQueryVariable() |
||
135 | { |
||
136 | $url = new Net_URL2( |
||
137 | 'http://www.example.com/?name=david&pear=fun&fish=slippery' |
||
138 | ); |
||
139 | |||
140 | $removes = array( |
||
141 | 'pear' => 'http://www.example.com/?name=david&fish=slippery', |
||
142 | 'name' => 'http://www.example.com/?fish=slippery', |
||
143 | 'fish' => 'http://www.example.com/', |
||
144 | ); |
||
145 | |||
146 | foreach ($removes as $name => $expected) { |
||
147 | $url->unsetQueryVariable($name); |
||
148 | $this->assertEquals($expected, $url); |
||
149 | } |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Tests setQuery(). |
||
154 | * |
||
155 | * @return void |
||
156 | */ |
||
157 | public function testSetQuery() |
||
158 | { |
||
159 | |||
160 | $url = new Net_URL2('http://www.example.com/'); |
||
161 | $url->setQuery('flapdoodle&dilly%20all%20day'); |
||
162 | $this->assertEquals( |
||
163 | $url->getURL(), 'http://www.example.com/?flapdoodle&dilly%20all%20day' |
||
164 | ); |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Tests getQuery(). |
||
169 | * |
||
170 | * @return void |
||
171 | */ |
||
172 | public function testGetQuery() |
||
173 | { |
||
174 | |||
175 | $url = new Net_URL2('http://www.example.com/?foo'); |
||
176 | $this->assertEquals($url->getQuery(), 'foo'); |
||
177 | $url = new Net_URL2('http://www.example.com/?pear=fun&fruit=fruity'); |
||
178 | $this->assertEquals($url->getQuery(), 'pear=fun&fruit=fruity'); |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * Tests setScheme(). |
||
183 | * |
||
184 | * @return void |
||
185 | */ |
||
186 | public function testSetScheme() |
||
187 | { |
||
188 | |||
189 | $url = new Net_URL2('http://www.example.com/'); |
||
190 | $url->setScheme('ftp'); |
||
191 | $this->assertEquals($url->getURL(), 'ftp://www.example.com/'); |
||
192 | $url->setScheme('gopher'); |
||
193 | $this->assertEquals($url->getURL(), 'gopher://www.example.com/'); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * Tests setting the fragment. |
||
198 | * |
||
199 | * @return void |
||
200 | */ |
||
201 | public function testSetFragment() |
||
202 | { |
||
203 | |||
204 | $url = new Net_URL2('http://www.example.com/'); |
||
205 | $url->setFragment('pear'); |
||
206 | $this->assertEquals('http://www.example.com/#pear', $url->getURL()); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * A dataProvider for paths that are solved to a base URI. |
||
211 | * |
||
212 | * @see testResolveUrls |
||
213 | * @return array |
||
214 | */ |
||
215 | public function provideResolveUrls() |
||
216 | { |
||
217 | return array( |
||
218 | array( |
||
219 | // Examples from RFC 3986, section 5.4. |
||
220 | // relative base-URI, (URL => absolute URL), [(options)] |
||
221 | 'http://a/b/c/d;p?q', |
||
222 | array( |
||
223 | 'g:h' => 'g:h', |
||
224 | 'g' => 'http://a/b/c/g', |
||
225 | './g' => 'http://a/b/c/g', |
||
226 | 'g/' => 'http://a/b/c/g/', |
||
227 | '/g' => 'http://a/g', |
||
228 | '//g' => 'http://g', |
||
229 | '?y' => 'http://a/b/c/d;p?y', |
||
230 | 'g?y' => 'http://a/b/c/g?y', |
||
231 | '#s' => 'http://a/b/c/d;p?q#s', |
||
232 | 'g#s' => 'http://a/b/c/g#s', |
||
233 | 'g?y#s' => 'http://a/b/c/g?y#s', |
||
234 | ';x' => 'http://a/b/c/;x', |
||
235 | 'g;x' => 'http://a/b/c/g;x', |
||
236 | 'g;x?y#s' => 'http://a/b/c/g;x?y#s', |
||
237 | '' => 'http://a/b/c/d;p?q', |
||
238 | '.' => 'http://a/b/c/', |
||
239 | './' => 'http://a/b/c/', |
||
240 | '..' => 'http://a/b/', |
||
241 | '../' => 'http://a/b/', |
||
242 | '../g' => 'http://a/b/g', |
||
243 | '../..' => 'http://a/', |
||
244 | '../../' => 'http://a/', |
||
245 | '../../g' => 'http://a/g', |
||
246 | '../../../g' => 'http://a/g', |
||
247 | '../../../../g' => 'http://a/g', |
||
248 | '/./g' => 'http://a/g', |
||
249 | '/../g' => 'http://a/g', |
||
250 | 'g.' => 'http://a/b/c/g.', |
||
251 | '.g' => 'http://a/b/c/.g', |
||
252 | 'g..' => 'http://a/b/c/g..', |
||
253 | '..g' => 'http://a/b/c/..g', |
||
254 | './../g' => 'http://a/b/g', |
||
255 | './g/.' => 'http://a/b/c/g/', |
||
256 | 'g/./h' => 'http://a/b/c/g/h', |
||
257 | 'g/../h' => 'http://a/b/c/h', |
||
258 | 'g;x=1/./y' => 'http://a/b/c/g;x=1/y', |
||
259 | 'g;x=1/../y' => 'http://a/b/c/y', |
||
260 | 'g?y/./x' => 'http://a/b/c/g?y/./x', |
||
261 | 'g?y/../x' => 'http://a/b/c/g?y/../x', |
||
262 | 'g#s/./x' => 'http://a/b/c/g#s/./x', |
||
263 | 'g#s/../x' => 'http://a/b/c/g#s/../x', |
||
264 | 'http:g' => 'http:g', |
||
265 | ), |
||
266 | ), |
||
267 | array( |
||
268 | 'http://a/b/c/d;p?q', |
||
269 | array('http:g' => 'http://a/b/c/g'), |
||
270 | array('::OPTION_STRICT' => false) |
||
271 | ), |
||
272 | ); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Test the resolve() function to resolve URLs to each other. |
||
277 | * |
||
278 | * @param string $baseURL base-URI |
||
279 | * @param array $relativeAbsolutePairs url-pairs, relative => resolved |
||
280 | * @param array $options Net_URL2 options |
||
281 | * |
||
282 | * @dataProvider provideResolveUrls |
||
283 | * @covers Net_URL2::resolve |
||
284 | * @return void |
||
285 | */ |
||
286 | public function testResolveUrls($baseURL, array $relativeAbsolutePairs, |
||
287 | array $options = array() |
||
288 | ) { |
||
289 | $options = $this->_translateOptionData($options); |
||
290 | $base = new Net_URL2($baseURL, $options); |
||
291 | $count = count($relativeAbsolutePairs); |
||
292 | $this->assertGreaterThan(0, $count, 'relative-absolute-pairs data is empty'); |
||
293 | foreach ($relativeAbsolutePairs as $relativeURL => $absoluteURL) { |
||
294 | $this->assertSame($absoluteURL, (string) $base->resolve($relativeURL)); |
||
295 | } |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * Helper method to turn options with strings as the constant names |
||
300 | * (to allow to externalize the fixtures) into a concrete options |
||
301 | * array that uses the values from the Net_URL2 class constants. |
||
302 | * |
||
303 | * @param array $options options |
||
304 | * |
||
305 | * @return array |
||
306 | */ |
||
307 | private function _translateOptionData(array $options) |
||
308 | { |
||
309 | // translate string option-names to class constant starting with a colon. |
||
310 | foreach ($options as $name => $value) { |
||
311 | if ($name[0] === ':') { |
||
312 | unset($options[$name]); |
||
313 | $options[constant("Net_URL2$name")] = $value; |
||
314 | } |
||
315 | } |
||
316 | return $options; |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Test the resolve() function throwing an exception with invalid data. |
||
321 | * |
||
322 | * @covers Net_URL2::resolve |
||
323 | * @return void |
||
324 | */ |
||
325 | public function testResolveException() |
||
326 | { |
||
327 | // resolving a relative to a relative URL throws an exception |
||
328 | $base = new Net_URL2('news.html?category=arts'); |
||
329 | $this->addToAssertionCount(1); |
||
330 | try { |
||
331 | $base->resolve('../arts.html#section-2.4'); |
||
332 | } catch (Exception $e) { |
||
333 | $expected = 'Base-URL must be absolute if reference is not fragment-onl'; |
||
334 | $this->assertStringStartsWith($expected, $e->getMessage()); |
||
335 | return; |
||
336 | } |
||
337 | $this->fail('Expected exception not thrown.'); |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Assert that there is a last error message and it contains needle. |
||
342 | * |
||
343 | * @param string $needle needle |
||
344 | * |
||
345 | * @return void |
||
346 | */ |
||
347 | private function _assertLastErrorContains($needle) |
||
348 | { |
||
349 | $error = error_get_last(); |
||
350 | $this->assertArrayHasKey('message', $error, 'there was an error previously'); |
||
351 | $pos = strpos($error['message'], $needle); |
||
352 | |||
353 | $this->assertTrue( |
||
354 | false !== $pos, |
||
355 | sprintf( |
||
356 | 'Last error message "%s" contains "%s"', $error['message'], $needle |
||
357 | ) |
||
358 | ); |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Test UrlEncoding |
||
363 | * |
||
364 | * @return void |
||
365 | * @link https://pear.php.net/bugs/bug.php?id=18267 |
||
366 | */ |
||
367 | public function testUrlEncoding() |
||
368 | { |
||
369 | $options = array(Net_URL2::OPTION_DROP_SEQUENCE => false); |
||
370 | $url = new Net_URL2('http://localhost/bug.php', $options); |
||
371 | $url->setQueryVariables( |
||
372 | array( |
||
373 | 'indexed' => array( |
||
374 | 'first value', 'second value', array('foo', 'bar'), |
||
375 | ) |
||
376 | ) |
||
377 | ); |
||
378 | $this->assertEquals( |
||
379 | 'http://localhost/bug.php?indexed[0]=first%20value&indexed[1]' . |
||
380 | '=second%20value&indexed[2][0]=foo&indexed[2][1]=bar', |
||
381 | strval($url) |
||
382 | ); |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * A test to verify that keys in QUERY_STRING are encoded by default. |
||
387 | * |
||
388 | * @return void |
||
389 | * @see Net_URL2::OPTION_ENCODE_KEYS |
||
390 | * @see Net_URL2::buildQuery() |
||
391 | */ |
||
392 | public function testEncodeKeys() |
||
393 | { |
||
394 | $url = new Net_URL2('http://example.org'); |
||
395 | $url->setQueryVariables(array('helgi rulez' => 'till too')); |
||
396 | $this->assertEquals( |
||
397 | 'http://example.org?helgi%20rulez=till%20too', |
||
398 | strval($url) |
||
399 | ); |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * A test to verify that keys in QUERY_STRING are not encoded when we supply |
||
404 | * 'false' via {@link Net_URL2::__construct()}. |
||
405 | * |
||
406 | * @return void |
||
407 | * @see Net_URL2::OPTION_ENCODE_KEYS |
||
408 | * @see Net_URL2::buildQuery() |
||
409 | */ |
||
410 | public function testDontEncodeKeys() |
||
411 | { |
||
412 | $url = new Net_URL2( |
||
413 | 'http://example.org', |
||
414 | array(Net_URL2::OPTION_ENCODE_KEYS => false) |
||
415 | ); |
||
416 | $url->setQueryVariables(array('till rulez' => 'helgi too')); |
||
417 | $this->assertEquals( |
||
418 | 'http://example.org?till rulez=helgi%20too', |
||
419 | strval($url) |
||
420 | ); |
||
421 | } |
||
422 | |||
423 | /** |
||
424 | * Brackets for array query variables |
||
425 | * |
||
426 | * Also text to not encode zero based integer sequence into brackets |
||
427 | * |
||
428 | * @return void |
||
429 | * |
||
430 | * @link https://pear.php.net/bugs/bug.php?id=20427 |
||
431 | */ |
||
432 | public function testUseBrackets() |
||
433 | { |
||
434 | $url = new Net_URL2('http://example.org/'); |
||
435 | $url->setQueryVariables(array('foo' => array('bar', 'baz'))); |
||
436 | $expected = 'http://example.org/?foo[]=bar&foo[]=baz'; |
||
437 | $this->assertEquals($expected, $url->getURL()); |
||
438 | |||
439 | $options = array(Net_URL2::OPTION_DROP_SEQUENCE => false); |
||
440 | $url = new Net_URL2('http://example.org/', $options); |
||
441 | $url->setQueryVariables(array('foo' => array('bar', 'foobar'))); |
||
442 | $expected = 'http://example.org/?foo[0]=bar&foo[1]=foobar'; |
||
443 | $this->assertEquals($expected, $url->getURL()); |
||
444 | } |
||
445 | |||
446 | /** |
||
447 | * Do not use brackets for query variables passed as array |
||
448 | * |
||
449 | * @return void |
||
450 | */ |
||
451 | public function testDontUseBrackets() |
||
452 | { |
||
453 | $url = new Net_URL2( |
||
454 | 'http://example.org/', |
||
455 | array(Net_URL2::OPTION_USE_BRACKETS => false) |
||
456 | ); |
||
457 | $url->setQueryVariables(array('foo' => array('bar', 'foobar'))); |
||
458 | $this->assertEquals( |
||
459 | 'http://example.org/?foo=bar&foo=foobar', |
||
460 | strval($url) |
||
461 | ); |
||
462 | } |
||
463 | |||
464 | /** |
||
465 | * A dataProvider for example URIs from RFC 3986 Section 1.1.2 |
||
466 | * |
||
467 | * @return array |
||
468 | * @link http://tools.ietf.org/html/rfc3986#section-1.1.2 |
||
469 | * @see testExampleUri |
||
470 | */ |
||
471 | public function provideExampleUri() |
||
472 | { |
||
473 | return array( |
||
474 | array('ftp://ftp.is.co.za/rfc/rfc1808.txt'), |
||
475 | array('http://www.ietf.org/rfc/rfc2396.txt'), |
||
476 | array('ldap://[2001:db8::7]/c=GB?objectClass?one'), |
||
477 | array('mailto:[email protected]'), |
||
478 | array('news:comp.infosystems.www.servers.unix'), |
||
479 | array('tel:+1-816-555-1212'), |
||
480 | array('telnet://192.0.2.16:80/'), |
||
481 | array('urn:oasis:names:specification:docbook:dtd:xml:4.1.2'), |
||
482 | ); |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * test that Net_URL2 works with the example URIs from RFC 3986 Section 1.1.2 |
||
487 | * |
||
488 | * @param string $uri example URI |
||
489 | * |
||
490 | * @return void |
||
491 | * @dataProvider provideExampleUri |
||
492 | * @link http://tools.ietf.org/html/rfc3986#section-1.1.2 |
||
493 | * @see testComponentRecompositionAndNormalization |
||
494 | */ |
||
495 | public function testExampleUri($uri) |
||
496 | { |
||
497 | $url = new Net_URL2($uri); |
||
498 | $this->assertSame($uri, $url->__toString()); |
||
499 | $url->normalize(); |
||
500 | $this->assertSame($uri, $url->__toString()); |
||
501 | } |
||
502 | |||
503 | /** |
||
504 | * A dataProvider for pairs of paths with dot segments and |
||
505 | * their form when removed. |
||
506 | * |
||
507 | * @see testRemoveDotSegments |
||
508 | * @return array |
||
509 | */ |
||
510 | public function providePath() |
||
511 | { |
||
512 | // The numbers behind are in reference to sections |
||
513 | // in RFC 3986 5.2.4. Remove Dot Segments |
||
514 | return array( |
||
515 | array('../', ''), // 2. A. |
||
516 | array('./', ''), // 2. A. |
||
517 | array('/./', '/'), // 2. B. |
||
518 | array('/.', '/'), // 2. B. |
||
519 | array('/../', '/'), // 2. C. |
||
520 | array('/..', '/'), // 2. C. |
||
521 | array('..', ''), // 2. D. |
||
522 | array('.', ''), // 2. D. |
||
523 | array('a', 'a'), // 2. E. |
||
524 | array('/a', '/a'), // 2. E. |
||
525 | array('/a/b/c/./../../g', '/a/g'), // 3. |
||
526 | array('mid/content=5/../6', 'mid/6'), // 3. |
||
527 | array('../foo/bar.php', 'foo/bar.php'), |
||
528 | array('/foo/../bar/boo.php', '/bar/boo.php'), |
||
529 | array('/boo/..//foo//bar.php', '//foo//bar.php'), |
||
530 | array('/./foo/././bar.php', '/foo/bar.php'), |
||
531 | array('./.', ''), |
||
532 | ); |
||
533 | } |
||
534 | |||
535 | /** |
||
536 | * Test removal of dot segments |
||
537 | * |
||
538 | * @param string $path Path |
||
539 | * @param string $assertion Assertion |
||
540 | * |
||
541 | * @dataProvider providePath |
||
542 | * @covers Net_URL2::removeDotSegments |
||
543 | * @return void |
||
544 | */ |
||
545 | public function testRemoveDotSegments($path, $assertion) |
||
546 | { |
||
547 | $this->assertEquals($assertion, Net_URL2::removeDotSegments($path)); |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * Test removeDotSegments() loop limit warning |
||
552 | * |
||
553 | * @covers Net_URL2::removeDotSegments |
||
554 | * @return void |
||
555 | */ |
||
556 | public function testRemoveDotSegmentsLoopLimit() |
||
557 | { |
||
558 | $loopLimit = 256; |
||
559 | $segments = str_repeat('a/', $loopLimit); |
||
560 | |||
561 | @Net_URL2::removeDotSegments($segments . 'b/'); |
||
0 ignored issues
–
show
|
|||
562 | |||
563 | $this->_assertLastErrorContains(sprintf(' loop limit %d ', $loopLimit + 1)); |
||
564 | $this->_assertLastErrorContains(" (left: '/b/')"); |
||
565 | } |
||
566 | |||
567 | /** |
||
568 | * A dataProvider for query strings and their array representation |
||
569 | * |
||
570 | * @see testGetQueryVariables |
||
571 | * @return array |
||
572 | */ |
||
573 | public function provideQueryStrings() |
||
574 | { |
||
575 | // If the second (expected) value is set or not null, parse_str() differs. |
||
576 | // Notes on PHP differences with each entry/block |
||
577 | return array( |
||
578 | // Net_URL2::getQueryVariables() non-bracket mode |
||
579 | array('test=1&t%65st=%41&extra=', |
||
580 | array('test' => array('1', 'A'), 'extra' => ''), |
||
581 | array('::OPTION_USE_BRACKETS' => false)), |
||
582 | array(''), |
||
583 | array('='), |
||
584 | array('key'), |
||
585 | array('key='), |
||
586 | array('=value'), |
||
587 | array('k=v'), |
||
588 | // no space as var-name in PHP (array()): |
||
589 | array(' ', array(' ' => '' )), |
||
590 | array(' =v', array(' ' => 'v')), |
||
591 | array('key=value'), |
||
592 | // PHP replaces ".", " " and "[" in name replaced by "_": |
||
593 | array('key.=value' , array('key.' => 'value')), |
||
594 | array('key =value' , array('key ' => 'value')), |
||
595 | array('key[=value' , array('key[' => 'value')), |
||
596 | array("key\0=value", array("key\0" => 'value')), |
||
597 | array('key]=value'), |
||
598 | array('key[]=value'), |
||
599 | array('[]=value'), |
||
600 | array(']=value'), |
||
601 | array(']]=value'), |
||
602 | // PHP drops variables that are an open bracket only |
||
603 | array('[=value', array('[' => 'value')), |
||
604 | // PHP drops spaces in brackets: |
||
605 | array('key[ ]=value', array('key' => array(' ' => 'value'))), |
||
606 | // PHP replaces space " " in name by "_" |
||
607 | array('key []=1' , array('key ' => array('1' ))) , |
||
608 | // PHP does not support "\0" in var-names: |
||
609 | array("key[\0]=value" , array('key' => array("\0" => 'value' ))), |
||
610 | array("key[a\0]=value" , array('key' => array("a\0" => 'value' ))), |
||
611 | array("key[a\0b]=value" , array('key' => array("a\0b" => 'value'))), |
||
612 | array('var[]=1&var[0][]=2'), |
||
613 | array('key[] []=1'), |
||
614 | array('key[] [] []=1'), |
||
615 | array('key[] [] []'), |
||
616 | array('key[] [] []=[] []'), |
||
617 | array('[] [] []=[] []'), |
||
618 | ); |
||
619 | } |
||
620 | |||
621 | /** |
||
622 | * Test parsing of query variables |
||
623 | * |
||
624 | * @param string $query string |
||
625 | * @param mixed $expected null to test against parse_str() behavior |
||
626 | * @param array $options Net_URL2 options |
||
627 | * |
||
628 | * @dataProvider provideQueryStrings |
||
629 | * @covers Net_URL2::getQueryVariables |
||
630 | * @covers Net_URL2::_queryArrayByKey |
||
631 | * @covers Net_URL2::_queryArrayByBrackets |
||
632 | * @covers Net_URL2::_queryKeyBracketOffset |
||
633 | * @return void |
||
634 | */ |
||
635 | public function testGetQueryVariables($query, $expected = null, |
||
636 | array $options = array() |
||
637 | ) { |
||
638 | $options = $this->_translateOptionData($options); |
||
639 | |||
640 | $url = new Net_URL2('', $options); |
||
641 | |||
642 | if ($expected === null) { |
||
643 | // parse_str() is in PHP before copy on write, therefore |
||
644 | // it uses pass-by-reference for $expected to return |
||
645 | // the array |
||
646 | parse_str($query, $expected); |
||
647 | } |
||
648 | |||
649 | // Xdebug: If breakpoints are ignored, see Xdebug Issue 0000924 |
||
650 | $url->setQuery($query); |
||
651 | $actual = $url->getQueryVariables(); |
||
652 | |||
653 | // Do two assertions, because the first one shows a more nice diff in case |
||
654 | // it fails and the second one is actually strict which is what has to be |
||
655 | // tested. |
||
656 | $this->assertEquals($expected, $actual); |
||
657 | $this->assertSame($expected, $actual); |
||
658 | } |
||
659 | |||
660 | /** |
||
661 | * data provider of host and port |
||
662 | * |
||
663 | * @return array |
||
664 | * @see testHostAndPort |
||
665 | */ |
||
666 | public function provideHostAndPort() |
||
667 | { |
||
668 | return array( |
||
669 | array('[::1]', '[::1]', false), |
||
670 | array('[::1]:', '[::1]', false), |
||
671 | array('[::1]:128', '[::1]', '128'), |
||
672 | array('127.0.0.1', '127.0.0.1', false), |
||
673 | array('127.0.0.1:', '127.0.0.1', false), |
||
674 | array('127.0.0.1:128', '127.0.0.1', '128'), |
||
675 | array('localhost', 'localhost', false), |
||
676 | array('localhost:', 'localhost', false), |
||
677 | array('localhost:128', 'localhost', '128'), |
||
678 | ); |
||
679 | } |
||
680 | |||
681 | /** |
||
682 | * test that an authority containing host and port maps to expected host and port |
||
683 | * |
||
684 | * This is also a regression test to test that using ip-literals works along- |
||
685 | * side ipv4 and reg-name hosts incl. port numbers |
||
686 | * |
||
687 | * It was reported as Bug #20423 on 2014-10-06 18:25 UTC that |
||
688 | * http://[::1]// URI drops the host |
||
689 | * |
||
690 | * @param string $authority string |
||
691 | * @param string $expectedHost string |
||
692 | * @param string|bool $expectedPort string or FALSE |
||
693 | * |
||
694 | * @return void |
||
695 | * @dataProvider provideHostAndPort |
||
696 | * @covers Net_URL2::setAuthority() |
||
697 | * @link https://pear.php.net/bugs/bug.php?id=20423 |
||
698 | * @link http://tools.ietf.org/html/rfc3986#section-3.2.2 |
||
699 | * @link http://tools.ietf.org/html/rfc3986#section-3.2 |
||
700 | * @link http://tools.ietf.org/html/rfc3986#section-3.2.3 |
||
701 | */ |
||
702 | public function testHostAndPort($authority, $expectedHost, $expectedPort) |
||
703 | { |
||
704 | $uri = "http://{$authority}"; |
||
705 | $url = new Net_URL2($uri); |
||
706 | $this->assertSame($expectedHost, $url->getHost()); |
||
707 | $this->assertSame($expectedPort, $url->getPort()); |
||
708 | } |
||
709 | |||
710 | /** |
||
711 | * This is a regression test to test that Net_URL2::getQueryVariables() does |
||
712 | * not have a problem with nested array values in form of stacked brackets and |
||
713 | * was reported as Bug #17036 on 2010-01-26 15:48 UTC that there would be |
||
714 | * a problem with parsed query string. |
||
715 | * |
||
716 | * @link https://pear.php.net/bugs/bug.php?id=17036 |
||
717 | * @covers Net_URL2::getQueryVariables |
||
718 | * @return void |
||
719 | */ |
||
720 | public function test17036() |
||
721 | { |
||
722 | $queryString = 'start=10&test[0][first][1.1][20]=coucou'; |
||
723 | $url = new Net_URL2('?' . $queryString); |
||
724 | $vars = $url->getQueryVariables(); |
||
725 | |||
726 | $expected = array(); |
||
727 | $expected['start'] = '10'; |
||
728 | $expected['test'][0]['first']['1.1'][20] = 'coucou'; |
||
729 | |||
730 | $this->assertEquals($expected, $vars); // give nice diff in case of failuer |
||
731 | $this->assertSame($expected, $vars); // strictly assert the premise |
||
732 | } |
||
733 | |||
734 | /** |
||
735 | * This is a regression test to test that resolve() does |
||
736 | * merge the path if the base path is empty as the opposite |
||
737 | * was reported as Bug #19176 on 2011-12-31 02:07 UTC |
||
738 | * |
||
739 | * @return void |
||
740 | */ |
||
741 | public function test19176() |
||
742 | { |
||
743 | $foo = new Net_URL2('http://www.example.com'); |
||
744 | $test = $foo->resolve('test.html')->getURL(); |
||
745 | $this->assertEquals('http://www.example.com/test.html', $test); |
||
746 | } |
||
747 | |||
748 | /** |
||
749 | * This is a regression test that removeDotSegments('0') is |
||
750 | * working as it was reported as not-working in Bug #19315 |
||
751 | * on 2012-03-04 04:18 UTC. |
||
752 | * |
||
753 | * @return void |
||
754 | */ |
||
755 | public function test19315() |
||
756 | { |
||
757 | $actual = Net_URL2::removeDotSegments('0'); |
||
758 | $this->assertSame('0', $actual); |
||
759 | |||
760 | $nonStringObject = (object)array(); |
||
761 | try { |
||
762 | Net_URL2::removeDotSegments($nonStringObject); |
||
763 | } catch (PHPUnit_Framework_Error $error) { |
||
764 | $this->addToAssertionCount(1); |
||
765 | } |
||
766 | |||
767 | if (!isset($error)) { |
||
768 | $this->fail('Failed to verify that error was given.'); |
||
769 | } |
||
770 | unset($error); |
||
771 | } |
||
772 | |||
773 | /** |
||
774 | * This is a regression test to test that recovering from |
||
775 | * a wrongly encoded URL is possible. |
||
776 | * |
||
777 | * It was requested as Request #19684 on 2011-12-31 02:07 UTC |
||
778 | * that redirects containing spaces should work. |
||
779 | * |
||
780 | * @return void |
||
781 | */ |
||
782 | public function test19684() |
||
783 | { |
||
784 | // Location: URL obtained Thu, 25 Apr 2013 20:51:31 GMT |
||
785 | $urlWithSpace = 'http://www.sigmaaldrich.com/catalog/search?interface=CAS N' |
||
786 | . 'o.&term=108-88-3&lang=en®ion=US&mode=match+partialmax&N=0+2200030' |
||
787 | . '48+219853269+219853286'; |
||
788 | |||
789 | $urlCorrect = 'http://www.sigmaaldrich.com/catalog/search?interface=CAS%20N' |
||
790 | . 'o.&term=108-88-3&lang=en®ion=US&mode=match+partialmax&N=0+2200030' |
||
791 | . '48+219853269+219853286'; |
||
792 | |||
793 | $url = new Net_URL2($urlWithSpace); |
||
794 | |||
795 | $this->assertTrue($url->isAbsolute()); |
||
796 | |||
797 | $urlPart = parse_url($urlCorrect, PHP_URL_PATH); |
||
798 | $this->assertSame($urlPart, $url->getPath()); |
||
799 | |||
800 | $urlPart = parse_url($urlCorrect, PHP_URL_QUERY); |
||
801 | $this->assertSame($urlPart, $url->getQuery()); |
||
802 | |||
803 | $this->assertSame($urlCorrect, (string)$url); |
||
804 | |||
805 | $input = 'http://example.com/get + + to my nose/'; |
||
806 | $expected = 'http://example.com/get%20+%20+%20to%20my%20nose/'; |
||
807 | $actual = new Net_URL2($input); |
||
808 | $this->assertEquals($expected, $actual); |
||
809 | $actual->normalize(); |
||
810 | } |
||
811 | |||
812 | /** |
||
813 | * data provider of list of equivalent URLs. |
||
814 | * |
||
815 | * @see testNormalize |
||
816 | * @see testConstructSelf |
||
817 | * @return array |
||
818 | */ |
||
819 | public function provideEquivalentUrlLists() |
||
820 | { |
||
821 | return array( |
||
822 | // String equivalence: |
||
823 | array('http://example.com/', 'http://example.com/'), |
||
824 | |||
825 | // Originally first dataset: |
||
826 | array('http://www.example.com/%9a', 'http://www.example.com/%9A'), |
||
827 | |||
828 | // Example from RFC 3986 6.2.2.: |
||
829 | array('example://a/b/c/%7Bfoo%7D', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d'), |
||
830 | |||
831 | // Example from RFC 3986 6.2.2.1.: |
||
832 | array('HTTP://www.EXAMPLE.com/', 'http://www.example.com/'), |
||
833 | |||
834 | // Example from RFC 3986 6.2.3.: |
||
835 | array( |
||
836 | 'http://example.com', 'http://example.com/', |
||
837 | 'http://example.com:/', 'http://example.com:80/' |
||
838 | ), |
||
839 | |||
840 | // Bug #20161: URLs with "0" as host fail to normalize with empty path |
||
841 | array('http://0/', 'http://0'), |
||
842 | |||
843 | // Bug #20473: Normalize query and fragment broken |
||
844 | array('foo:///?%66%6f%6f#%62%61%72', 'foo:///?foo#bar'), |
||
845 | ); |
||
846 | } |
||
847 | |||
848 | /** |
||
849 | * This is a coverage test to invoke the normalize() |
||
850 | * method. |
||
851 | * |
||
852 | * @return void |
||
853 | * |
||
854 | * @dataProvider provideEquivalentUrlLists |
||
855 | */ |
||
856 | public function testNormalize() |
||
857 | { |
||
858 | $urls = func_get_args(); |
||
859 | |||
860 | $this->assertGreaterThanOrEqual(2, count($urls)); |
||
861 | |||
862 | $last = null; |
||
863 | |||
864 | foreach ($urls as $index => $url) { |
||
865 | $url = new Net_Url2($url); |
||
866 | $url->normalize(); |
||
867 | if ($index) { |
||
868 | $this->assertSame((string)$last, (string)$url); |
||
869 | } |
||
870 | $last = $url; |
||
871 | } |
||
872 | } |
||
873 | |||
874 | /** |
||
875 | * This is a coverage test to invoke __get and __set |
||
876 | * |
||
877 | * @covers Net_URL2::__get |
||
878 | * @covers Net_URL2::__set |
||
879 | * @return void |
||
880 | */ |
||
881 | public function testMagicSetGet() |
||
882 | { |
||
883 | $url = new Net_URL2(''); |
||
884 | |||
885 | $property = 'authority'; |
||
886 | $url->$property = $value = 'value'; |
||
887 | $this->assertEquals($value, $url->$property); |
||
888 | |||
889 | $property = 'unsetProperty'; |
||
890 | $url->$property = $value; |
||
891 | $this->assertEquals(false, $url->$property); |
||
892 | } |
||
893 | |||
894 | /** |
||
895 | * data provider of uri and normal URIs |
||
896 | * |
||
897 | * @return array |
||
898 | * @see testComponentRecompositionAndNormalization |
||
899 | */ |
||
900 | public function provideComposedAndNormalized() |
||
901 | { |
||
902 | return array( |
||
903 | array(''), |
||
904 | array('http:g'), |
||
905 | array('user@host'), |
||
906 | array('mailto:user@host'), |
||
907 | ); |
||
908 | } |
||
909 | |||
910 | /** |
||
911 | * Tests Net_URL2 RFC 3986 5.3. Component Recomposition in the light |
||
912 | * of normalization |
||
913 | * |
||
914 | * This is also a regression test to test that a missing authority works well |
||
915 | * with normalization |
||
916 | * |
||
917 | * It was reported as Bug #20418 on 2014-10-02 22:10 UTC that there is an |
||
918 | * Incorrect normalization of URI with missing authority |
||
919 | * |
||
920 | * @param string $uri URI |
||
921 | * |
||
922 | * @return void |
||
923 | * @covers Net_URL2::getUrl() |
||
924 | * @covers Net_URL2::normalize() |
||
925 | * @dataProvider provideComposedAndNormalized |
||
926 | * @link https://pear.php.net/bugs/bug.php?id=20418 |
||
927 | * @see testExampleUri |
||
928 | */ |
||
929 | public function testComponentRecompositionAndNormalization($uri) |
||
930 | { |
||
931 | $url = new Net_URL2($uri); |
||
932 | $this->assertSame($uri, $url->getURL()); |
||
933 | $url->normalize(); |
||
934 | $this->assertSame($uri, $url->getURL()); |
||
935 | } |
||
936 | |||
937 | /** |
||
938 | * Tests Net_URL2 ctors URL parameter works with objects implementing |
||
939 | * __toString(). |
||
940 | * |
||
941 | * @dataProvider provideEquivalentUrlLists |
||
942 | * @coversNothing |
||
943 | * @return void |
||
944 | */ |
||
945 | public function testConstructSelf() |
||
946 | { |
||
947 | $urls = func_get_args(); |
||
948 | foreach ($urls as $url) { |
||
949 | $urlA = new Net_URL2($url); |
||
950 | $urlB = new Net_URL2($urlA); |
||
951 | $this->assertSame((string)$urlA, (string)$urlB); |
||
952 | } |
||
953 | } |
||
954 | |||
955 | /** |
||
956 | * This is a feature test to see that the userinfo's data is getting |
||
957 | * encoded as outlined in #19684. |
||
958 | * |
||
959 | * @covers Net_URL2::setAuthority |
||
960 | * @covers Net_URL2::setUserinfo |
||
961 | * @return void |
||
962 | */ |
||
963 | public function testEncodeDataUserinfoAuthority() |
||
964 | { |
||
965 | $url = new Net_URL2('http://john doe:[email protected]/'); |
||
966 | $this->assertSame('http://john%20doe:[email protected]/', (string)$url); |
||
967 | |||
968 | $url->setUserinfo('john doe'); |
||
969 | $this->assertSame('http://john%[email protected]/', (string)$url); |
||
970 | |||
971 | $url->setUserinfo('john doe', 'pa wd'); |
||
972 | $this->assertSame('http://john%20doe:pa%[email protected]/', (string)$url); |
||
973 | } |
||
974 | |||
975 | /** |
||
976 | * This is a regression test to test that using the |
||
977 | * host-name "0" does work with getAuthority() |
||
978 | * |
||
979 | * It was reported as Bug #20156 on 2013-12-27 22:56 UTC |
||
980 | * that setAuthority() with "0" as host would not work |
||
981 | * |
||
982 | * @covers Net_URL2::setAuthority |
||
983 | * @covers Net_URL2::getAuthority |
||
984 | * @covers Net_URL2::setHost |
||
985 | * @return void |
||
986 | */ |
||
987 | public function test20156() |
||
988 | { |
||
989 | $url = new Net_URL2('http://user:[email protected]:127/'); |
||
990 | $host = '0'; |
||
991 | $url->setHost($host); |
||
992 | $this->assertSame('user:pass@0:127', $url->getAuthority()); |
||
993 | |||
994 | $url->setHost(false); |
||
995 | $this->assertSame(false, $url->getAuthority()); |
||
996 | |||
997 | $url->setAuthority($host); |
||
998 | $this->assertSame($host, $url->getAuthority()); |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * This is a regression test to test that setting "0" as path |
||
1003 | * does not break normalize(). |
||
1004 | * |
||
1005 | * It was reported as Bug #20157 on 2013-12-27 23:42 UTC that |
||
1006 | * normalize() with "0" as path would not work. |
||
1007 | * |
||
1008 | * @covers Net_URL2::normalize |
||
1009 | * @return void |
||
1010 | */ |
||
1011 | public function test20157() |
||
1012 | { |
||
1013 | $subject = 'http://example.com'; |
||
1014 | $url = new Net_URL2($subject); |
||
1015 | $url->setPath('0'); |
||
1016 | $url->normalize(); |
||
1017 | $this->assertSame("$subject/0", (string)$url); |
||
1018 | } |
||
1019 | |||
1020 | /** |
||
1021 | * This is a regression test to ensure that fragment-only references can be |
||
1022 | * resolved to a non-absolute Base-URI. |
||
1023 | * |
||
1024 | * It was reported as Bug #20158 2013-12-28 14:49 UTC that fragment-only |
||
1025 | * references would not be resolved to non-absolute base URI |
||
1026 | * |
||
1027 | * @covers Net_URL2::resolve |
||
1028 | * @covers Net_URL2::_isFragmentOnly |
||
1029 | * @return void |
||
1030 | */ |
||
1031 | public function test20158() |
||
1032 | { |
||
1033 | $base = new Net_URL2('myfile.html'); |
||
1034 | $resolved = $base->resolve('#world'); |
||
1035 | $this->assertSame('myfile.html#world', (string)$resolved); |
||
1036 | } |
||
1037 | |||
1038 | /** |
||
1039 | * This is a regression test to ensure that authority and path are properly |
||
1040 | * combined when the path does not start with a slash which is the separator |
||
1041 | * character between authority and path. |
||
1042 | * |
||
1043 | * It was reported as Bug #20159 2013-12-28 17:18 UTC that authority |
||
1044 | * would not be terminated by slash |
||
1045 | * |
||
1046 | * @covers Net_URL2::getUrl |
||
1047 | * @return void |
||
1048 | */ |
||
1049 | public function test20159() |
||
1050 | { |
||
1051 | $url = new Net_URL2('index.html'); |
||
1052 | $url->setHost('example.com'); |
||
1053 | $this->assertSame('//example.com/index.html', (string)$url); |
||
1054 | } |
||
1055 | |||
1056 | /** |
||
1057 | * This is a regression test to test that using the file:// URI scheme with |
||
1058 | * an empty (default) hostname has the empty authority preserved when the |
||
1059 | * full URL is build. |
||
1060 | * |
||
1061 | * It was reported as Bug #20304 on 2014-06-21 00:06 UTC |
||
1062 | * that file:// URI are crippled. |
||
1063 | * |
||
1064 | * Tests with a default authority for the "file" URI scheme |
||
1065 | * |
||
1066 | * @covers Net_URL2::getURL |
||
1067 | * @return void |
||
1068 | * @link https://pear.php.net/bugs/bug.php?id=20304 |
||
1069 | */ |
||
1070 | public function test20304() |
||
1071 | { |
||
1072 | $file = 'file:///path/to/file'; |
||
1073 | $url = new Net_URL2($file); |
||
1074 | $this->assertSame($file, (string) $url); |
||
1075 | |||
1076 | $file = 'file://localhost/path/to/file'; |
||
1077 | $url = new Net_URL2($file); |
||
1078 | $this->assertSame($file, (string) $url); |
||
1079 | |||
1080 | $file = 'file://user@/path/to/file'; |
||
1081 | $url = new Net_URL2($file); |
||
1082 | $this->assertSame($file, (string) $url); |
||
1083 | |||
1084 | $file = 'FILE:///path/to/file'; |
||
1085 | $url = new Net_URL2($file); |
||
1086 | $this->assertSame($file, (string) $url); |
||
1087 | } |
||
1088 | } |
||
1089 |
If you suppress an error, we recommend checking for the error condition explicitly: