HostnameTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Validate
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_Validate_Hostname
  24. */
  25. require_once 'Zend/Validate/Hostname.php';
  26. /**
  27. * @category Zend
  28. * @package Zend_Validate
  29. * @subpackage UnitTests
  30. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. * @group Zend_Validate
  33. */
  34. class Zend_Validate_HostnameTest extends PHPUnit_Framework_TestCase
  35. {
  36. /**
  37. * Default instance created for all test methods
  38. *
  39. * @var Zend_Validate_Hostname
  40. */
  41. protected $_validator;
  42. /**
  43. * Creates a new Zend_Validate_Hostname object for each test method
  44. *
  45. * @return void
  46. */
  47. public function setUp()
  48. {
  49. $this->_origEncoding = PHP_VERSION_ID < 50600
  50. ? iconv_get_encoding('internal_encoding')
  51. : ini_get('default_charset');
  52. $this->_validator = new Zend_Validate_Hostname();
  53. }
  54. /**
  55. * Reset iconv
  56. */
  57. public function tearDown()
  58. {
  59. if (PHP_VERSION_ID < 50600) {
  60. iconv_set_encoding('internal_encoding', $this->_origEncoding);
  61. } else {
  62. ini_set('default_charset', $this->_origEncoding);
  63. }
  64. }
  65. /**
  66. * Ensures that the validator follows expected behavior
  67. *
  68. * @return void
  69. */
  70. public function testBasic()
  71. {
  72. $valuesExpected = array(
  73. array(Zend_Validate_Hostname::ALLOW_IP, true, array('1.2.3.4', '10.0.0.1', '255.255.255.255')),
  74. array(Zend_Validate_Hostname::ALLOW_IP, false, array('1.2.3.4.5', '0.0.0.256')),
  75. array(Zend_Validate_Hostname::ALLOW_DNS, true, array('example.com', 'example.museum', 'd.hatena.ne.jp')),
  76. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('localhost', 'localhost.localdomain', '1.2.3.4', 'domain.invalid')),
  77. array(Zend_Validate_Hostname::ALLOW_LOCAL, true, array('localhost', 'localhost.localdomain', 'example.com')),
  78. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('localhost', 'example.com', '1.2.3.4')),
  79. array(Zend_Validate_Hostname::ALLOW_LOCAL, false, array('local host', 'example,com', 'exam_ple.com'))
  80. );
  81. foreach ($valuesExpected as $element) {
  82. $validator = new Zend_Validate_Hostname($element[0]);
  83. foreach ($element[2] as $input) {
  84. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  85. }
  86. }
  87. }
  88. public function testCombination()
  89. {
  90. $valuesExpected = array(
  91. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_LOCAL, true, array('domain.com', 'localhost', 'local.localhost')),
  92. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_LOCAL, false, array('1.2.3.4', '255.255.255.255')),
  93. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_IP, true, array('1.2.3.4', '255.255.255.255')),
  94. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_IP, false, array('localhost', 'local.localhost'))
  95. );
  96. foreach ($valuesExpected as $element) {
  97. $validator = new Zend_Validate_Hostname($element[0]);
  98. foreach ($element[2] as $input) {
  99. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  100. }
  101. }
  102. }
  103. /**
  104. * Ensure the dash character tests work as expected
  105. *
  106. */
  107. public function testDashes()
  108. {
  109. $valuesExpected = array(
  110. array(Zend_Validate_Hostname::ALLOW_DNS, true, array('domain.com', 'doma-in.com')),
  111. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('-domain.com', 'domain-.com', 'do--main.com'))
  112. );
  113. foreach ($valuesExpected as $element) {
  114. $validator = new Zend_Validate_Hostname($element[0]);
  115. foreach ($element[2] as $input) {
  116. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  117. }
  118. }
  119. }
  120. /**
  121. * Ensures that getMessages() returns expected default value
  122. *
  123. * @return void
  124. */
  125. public function testGetMessages()
  126. {
  127. $this->assertEquals(array(), $this->_validator->getMessages());
  128. }
  129. /**
  130. * Ensure the IDN check works as expected
  131. *
  132. */
  133. public function testIDN()
  134. {
  135. $validator = new Zend_Validate_Hostname();
  136. // Check IDN matching
  137. $valuesExpected = array(
  138. array(true, array('bürger.de', 'hãllo.de', 'hållo.se')),
  139. array(true, array('bÜrger.de', 'hÃllo.de', 'hÅllo.se')),
  140. array(false, array('hãllo.se', 'bürger.lt', 'hãllo.uk'))
  141. );
  142. foreach ($valuesExpected as $element) {
  143. foreach ($element[1] as $input) {
  144. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  145. }
  146. }
  147. // Check no IDN matching
  148. $validator->setValidateIdn(false);
  149. $valuesExpected = array(
  150. array(false, array('bürger.de', 'hãllo.de', 'hållo.se'))
  151. );
  152. foreach ($valuesExpected as $element) {
  153. foreach ($element[1] as $input) {
  154. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  155. }
  156. }
  157. // Check setting no IDN matching via constructor
  158. unset($validator);
  159. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, false);
  160. $valuesExpected = array(
  161. array(false, array('bürger.de', 'hãllo.de', 'hållo.se'))
  162. );
  163. foreach ($valuesExpected as $element) {
  164. foreach ($element[1] as $input) {
  165. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  166. }
  167. }
  168. }
  169. /**
  170. * Ensure the IDN check works on ressource files as expected
  171. *
  172. */
  173. public function testRessourceIDN()
  174. {
  175. $validator = new Zend_Validate_Hostname();
  176. // Check IDN matching
  177. $valuesExpected = array(
  178. array(true, array('bürger.com', 'hãllo.com', 'hållo.com')),
  179. array(true, array('bÜrger.com', 'hÃllo.com', 'hÅllo.com')),
  180. array(false, array('hãllo.lt', 'bürger.lt', 'hãllo.lt'))
  181. );
  182. foreach ($valuesExpected as $element) {
  183. foreach ($element[1] as $input) {
  184. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  185. }
  186. }
  187. // Check no IDN matching
  188. $validator->setValidateIdn(false);
  189. $valuesExpected = array(
  190. array(false, array('bürger.com', 'hãllo.com', 'hållo.com'))
  191. );
  192. foreach ($valuesExpected as $element) {
  193. foreach ($element[1] as $input) {
  194. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  195. }
  196. }
  197. // Check setting no IDN matching via constructor
  198. unset($validator);
  199. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, false);
  200. $valuesExpected = array(
  201. array(false, array('bürger.com', 'hãllo.com', 'hållo.com'))
  202. );
  203. foreach ($valuesExpected as $element) {
  204. foreach ($element[1] as $input) {
  205. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  206. }
  207. }
  208. }
  209. /**
  210. * Ensure the TLD check works as expected
  211. *
  212. */
  213. public function testTLD()
  214. {
  215. $validator = new Zend_Validate_Hostname();
  216. // Check TLD matching
  217. $valuesExpected = array(
  218. array(true, array('domain.co.uk', 'domain.uk.com', 'domain.tl', 'domain.zw', 'domain.menu', 'domain.versicherung')),
  219. array(false, array('domain.xx', 'domain.zz', 'domain.madeup'))
  220. );
  221. foreach ($valuesExpected as $element) {
  222. foreach ($element[1] as $input) {
  223. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  224. }
  225. }
  226. // Check no TLD matching
  227. $validator->setValidateTld(false);
  228. $valuesExpected = array(
  229. array(true, array('domain.xx', 'domain.zz', 'domain.madeup'))
  230. );
  231. foreach ($valuesExpected as $element) {
  232. foreach ($element[1] as $input) {
  233. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  234. }
  235. }
  236. // Check setting no TLD matching via constructor
  237. unset($validator);
  238. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, true, false);
  239. $valuesExpected = array(
  240. array(true, array('domain.xx', 'domain.zz', 'domain.madeup'))
  241. );
  242. foreach ($valuesExpected as $element) {
  243. foreach ($element[1] as $input) {
  244. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  245. }
  246. }
  247. }
  248. /**
  249. * Ensures that getAllow() returns expected default value
  250. *
  251. * @return void
  252. */
  253. public function testGetAllow()
  254. {
  255. $this->assertEquals(Zend_Validate_Hostname::ALLOW_DNS, $this->_validator->getAllow());
  256. }
  257. /**
  258. * Test changed with ZF-6676, as IP check is only involved when IP patterns match
  259. *
  260. * @group ZF-2861
  261. * @group ZF-6676
  262. */
  263. public function testValidatorMessagesShouldBeTranslated()
  264. {
  265. require_once 'Zend/Translate.php';
  266. $translations = array(
  267. 'hostnameInvalidLocalName' => 'this is the IP error message',
  268. );
  269. $translator = new Zend_Translate('array', $translations);
  270. $this->_validator->setTranslator($translator);
  271. $this->_validator->isValid('0.239,512.777');
  272. $messages = $this->_validator->getMessages();
  273. $found = false;
  274. foreach ($messages as $code => $message) {
  275. if (array_key_exists($code, $translations)) {
  276. $found = true;
  277. break;
  278. }
  279. }
  280. $this->assertTrue($found);
  281. $this->assertEquals($translations[$code], $message);
  282. }
  283. /**
  284. * @group ZF-6033
  285. */
  286. public function testNumberNames()
  287. {
  288. $validator = new Zend_Validate_Hostname();
  289. // Check TLD matching
  290. $valuesExpected = array(
  291. array(true, array('www.danger1.com', 'danger.com', 'www.danger.com')),
  292. array(false, array('www.danger1com', 'dangercom', 'www.dangercom'))
  293. );
  294. foreach ($valuesExpected as $element) {
  295. foreach ($element[1] as $input) {
  296. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  297. }
  298. }
  299. }
  300. /**
  301. * @group ZF-6133
  302. */
  303. public function testPunycodeDecoding()
  304. {
  305. $validator = new Zend_Validate_Hostname();
  306. // Check TLD matching
  307. $valuesExpected = array(
  308. array(true, array('xn--brger-kva.com', 'xn--eckwd4c7cu47r2wf.jp')),
  309. array(false, array('xn--brger-x45d2va.com', 'xn--bürger.com', 'xn--'))
  310. );
  311. foreach ($valuesExpected as $element) {
  312. foreach ($element[1] as $input) {
  313. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  314. }
  315. }
  316. }
  317. /**
  318. * @ZF-4352
  319. */
  320. public function testNonStringValidation()
  321. {
  322. $this->assertFalse($this->_validator->isValid(array(1 => 1)));
  323. }
  324. /**
  325. * @ZF-7323
  326. */
  327. public function testLatinSpecialChars()
  328. {
  329. $this->assertFalse($this->_validator->isValid('place@yah&oo.com'));
  330. $this->assertFalse($this->_validator->isValid('place@y*ahoo.com'));
  331. $this->assertFalse($this->_validator->isValid('ya#hoo'));
  332. }
  333. /**
  334. * @group ZF-7277
  335. */
  336. public function testDifferentIconvEncoding()
  337. {
  338. if (PHP_VERSION_ID < 50600) {
  339. iconv_set_encoding('internal_encoding', 'ISO8859-1');
  340. } else {
  341. ini_set('default_charset', 'ISO8859-1');
  342. }
  343. $validator = new Zend_Validate_Hostname();
  344. $valuesExpected = array(
  345. array(true, array('bürger.com', 'hãllo.com', 'hållo.com')),
  346. array(true, array('bÜrger.com', 'hÃllo.com', 'hÅllo.com')),
  347. array(false, array('hãllo.lt', 'bürger.lt', 'hãllo.lt'))
  348. );
  349. foreach ($valuesExpected as $element) {
  350. foreach ($element[1] as $input) {
  351. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  352. }
  353. }
  354. }
  355. /**
  356. * @ZF-8312
  357. */
  358. public function testInvalidDoubledIdn()
  359. {
  360. $this->assertFalse($this->_validator->isValid('test.com / http://www.test.com'));
  361. }
  362. /**
  363. * @group ZF-10267
  364. */
  365. public function testURI()
  366. {
  367. $valuesExpected = array(
  368. array(Zend_Validate_Hostname::ALLOW_URI, true, array('localhost', 'example.com', '~ex%20ample')),
  369. array(Zend_Validate_Hostname::ALLOW_URI, false, array('§bad', 'don?t.know', 'thisisaverylonghostnamewhichextendstwohundredfiftysixcharactersandthereforshouldnotbeallowedbythisvalidatorbecauserfc3986limitstheallowedcharacterstoalimitoftwohunderedfiftysixcharactersinsumbutifthistestwouldfailthenitshouldreturntruewhichthrowsanexceptionbytheunittest')),
  370. );
  371. foreach ($valuesExpected as $element) {
  372. $validator = new Zend_Validate_Hostname($element[0]);
  373. foreach ($element[2] as $input) {
  374. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  375. }
  376. }
  377. }
  378. /**
  379. * Ensure that a trailing "." in a local hostname is permitted
  380. *
  381. * @group ZF-6363
  382. */
  383. public function testTrailingDot()
  384. {
  385. $valuesExpected = array(
  386. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('example.', 'example.com.', '~ex%20ample.com.')),
  387. array(Zend_Validate_Hostname::ALLOW_ALL, false, array('example..',)),
  388. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('1.2.3.4.')),
  389. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('example..', '~ex%20ample..')),
  390. array(Zend_Validate_Hostname::ALLOW_LOCAL, true, array('example.', 'example.com.')),
  391. );
  392. foreach ($valuesExpected as $element) {
  393. $validator = new Zend_Validate_Hostname($element[0]);
  394. foreach ($element[2] as $input) {
  395. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  396. }
  397. }
  398. }
  399. /**
  400. * @group ZF-11334
  401. * @see http://www.ietf.org/rfc/rfc2732.txt
  402. */
  403. public function testSupportsIpv6AddressesWhichContainHexDigitF()
  404. {
  405. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  406. $this->assertTrue($validator->isValid('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210'));
  407. $this->assertTrue($validator->isValid('1080:0:0:0:8:800:200C:417A'));
  408. $this->assertTrue($validator->isValid('3ffe:2a00:100:7031::1'));
  409. $this->assertTrue($validator->isValid('1080::8:800:200C:417A'));
  410. $this->assertTrue($validator->isValid('::192.9.5.5'));
  411. $this->assertTrue($validator->isValid('::FFFF:129.144.52.38'));
  412. $this->assertTrue($validator->isValid('2010:836B:4179::836B:4179'));
  413. }
  414. /**
  415. * @group ZF-11796
  416. */
  417. public function testIDNSI()
  418. {
  419. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  420. $this->assertTrue($validator->isValid('Test123.si'));
  421. $this->assertTrue($validator->isValid('țest123.si'));
  422. $this->assertTrue($validator->isValid('tĕst123.si'));
  423. $this->assertTrue($validator->isValid('tàrø.si'));
  424. $this->assertFalse($validator->isValid('رات.si'));
  425. }
  426. /**
  427. * @ZF-12314
  428. */
  429. public function testDKSpecialChars()
  430. {
  431. $this->assertTrue($this->_validator->isValid('testæøå.dk'));
  432. }
  433. /**
  434. * test for IDN CA
  435. */
  436. public function testIDNCA()
  437. {
  438. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  439. $this->assertTrue($validator->isValid('Test123.ca'));
  440. $this->assertTrue($validator->isValid('tàr.ca'));
  441. $this->assertFalse($validator->isValid('țest123.ca'));
  442. $this->assertFalse($validator->isValid('tĕst123.ca'));
  443. $this->assertFalse($validator->isValid('رات.ca'));
  444. }
  445. /**
  446. * @group ZF-12413
  447. */
  448. public function testIDNUA()
  449. {
  450. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  451. $this->assertTrue($validator->isValid('самобраноч.com.ua'));
  452. $this->assertTrue($validator->isValid('hostmaster.ua'));
  453. }
  454. /**
  455. * Test for IDN serbia .rs
  456. *
  457. * @group GH-115
  458. */
  459. public function testIDNRS()
  460. {
  461. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  462. $this->assertTrue($validator->isValid('test.rs'));
  463. }
  464. /**
  465. * @group GH-19
  466. */
  467. public function testRussianIdn()
  468. {
  469. $validator = new Zend_Validate_Hostname();
  470. $this->assertTrue($validator->isValid('кц.рф'));
  471. $this->assertTrue($validator->isValid('президент.рф'));
  472. }
  473. /**
  474. * @group GH-451
  475. */
  476. public function testVermögensberaterIdns()
  477. {
  478. $validator = new Zend_Validate_Hostname();
  479. $this->assertTrue($validator->isValid('mysite.vermögensberater'));
  480. }
  481. /**
  482. * @group GH-610
  483. */
  484. public function testGermanSmallLetterSharpS()
  485. {
  486. $validator = new Zend_Validate_Hostname();
  487. $this->assertTrue($validator->isValid('straße.de'));
  488. }
  489. /**
  490. * @group GH-612
  491. */
  492. public function testZeroSubdomain()
  493. {
  494. $validator = new Zend_Validate_Hostname();
  495. $this->assertTrue($validator->isValid('1.pool.ntp.org'));
  496. $this->assertTrue($validator->isValid('0.pool.ntp.org'));
  497. }
  498. }