HostnameTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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-2014 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-2014 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 = iconv_get_encoding('internal_encoding');
  50. $this->_validator = new Zend_Validate_Hostname();
  51. }
  52. /**
  53. * Reset iconv
  54. */
  55. public function tearDown()
  56. {
  57. iconv_set_encoding('internal_encoding', $this->_origEncoding);
  58. }
  59. /**
  60. * Ensures that the validator follows expected behavior
  61. *
  62. * @return void
  63. */
  64. public function testBasic()
  65. {
  66. $valuesExpected = array(
  67. array(Zend_Validate_Hostname::ALLOW_IP, true, array('1.2.3.4', '10.0.0.1', '255.255.255.255')),
  68. array(Zend_Validate_Hostname::ALLOW_IP, false, array('1.2.3.4.5', '0.0.0.256')),
  69. array(Zend_Validate_Hostname::ALLOW_DNS, true, array('example.com', 'example.museum', 'd.hatena.ne.jp')),
  70. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('localhost', 'localhost.localdomain', '1.2.3.4', 'domain.invalid')),
  71. array(Zend_Validate_Hostname::ALLOW_LOCAL, true, array('localhost', 'localhost.localdomain', 'example.com')),
  72. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('localhost', 'example.com', '1.2.3.4')),
  73. array(Zend_Validate_Hostname::ALLOW_LOCAL, false, array('local host', 'example,com', 'exam_ple.com'))
  74. );
  75. foreach ($valuesExpected as $element) {
  76. $validator = new Zend_Validate_Hostname($element[0]);
  77. foreach ($element[2] as $input) {
  78. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  79. }
  80. }
  81. }
  82. public function testCombination()
  83. {
  84. $valuesExpected = array(
  85. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_LOCAL, true, array('domain.com', 'localhost', 'local.localhost')),
  86. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_LOCAL, false, array('1.2.3.4', '255.255.255.255')),
  87. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_IP, true, array('1.2.3.4', '255.255.255.255')),
  88. array(Zend_Validate_Hostname::ALLOW_DNS | Zend_Validate_Hostname::ALLOW_IP, false, array('localhost', 'local.localhost'))
  89. );
  90. foreach ($valuesExpected as $element) {
  91. $validator = new Zend_Validate_Hostname($element[0]);
  92. foreach ($element[2] as $input) {
  93. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  94. }
  95. }
  96. }
  97. /**
  98. * Ensure the dash character tests work as expected
  99. *
  100. */
  101. public function testDashes()
  102. {
  103. $valuesExpected = array(
  104. array(Zend_Validate_Hostname::ALLOW_DNS, true, array('domain.com', 'doma-in.com')),
  105. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('-domain.com', 'domain-.com', 'do--main.com'))
  106. );
  107. foreach ($valuesExpected as $element) {
  108. $validator = new Zend_Validate_Hostname($element[0]);
  109. foreach ($element[2] as $input) {
  110. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  111. }
  112. }
  113. }
  114. /**
  115. * Ensures that getMessages() returns expected default value
  116. *
  117. * @return void
  118. */
  119. public function testGetMessages()
  120. {
  121. $this->assertEquals(array(), $this->_validator->getMessages());
  122. }
  123. /**
  124. * Ensure the IDN check works as expected
  125. *
  126. */
  127. public function testIDN()
  128. {
  129. $validator = new Zend_Validate_Hostname();
  130. // Check IDN matching
  131. $valuesExpected = array(
  132. array(true, array('bürger.de', 'hãllo.de', 'hållo.se')),
  133. array(true, array('bÜrger.de', 'hÃllo.de', 'hÅllo.se')),
  134. array(false, array('hãllo.se', 'bürger.lt', 'hãllo.uk'))
  135. );
  136. foreach ($valuesExpected as $element) {
  137. foreach ($element[1] as $input) {
  138. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  139. }
  140. }
  141. // Check no IDN matching
  142. $validator->setValidateIdn(false);
  143. $valuesExpected = array(
  144. array(false, array('bürger.de', 'hãllo.de', 'hållo.se'))
  145. );
  146. foreach ($valuesExpected as $element) {
  147. foreach ($element[1] as $input) {
  148. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  149. }
  150. }
  151. // Check setting no IDN matching via constructor
  152. unset($validator);
  153. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, false);
  154. $valuesExpected = array(
  155. array(false, array('bürger.de', 'hãllo.de', 'hållo.se'))
  156. );
  157. foreach ($valuesExpected as $element) {
  158. foreach ($element[1] as $input) {
  159. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  160. }
  161. }
  162. }
  163. /**
  164. * Ensure the IDN check works on ressource files as expected
  165. *
  166. */
  167. public function testRessourceIDN()
  168. {
  169. $validator = new Zend_Validate_Hostname();
  170. // Check IDN matching
  171. $valuesExpected = array(
  172. array(true, array('bürger.com', 'hãllo.com', 'hållo.com')),
  173. array(true, array('bÜrger.com', 'hÃllo.com', 'hÅllo.com')),
  174. array(false, array('hãllo.lt', 'bürger.lt', 'hãllo.lt'))
  175. );
  176. foreach ($valuesExpected as $element) {
  177. foreach ($element[1] as $input) {
  178. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  179. }
  180. }
  181. // Check no IDN matching
  182. $validator->setValidateIdn(false);
  183. $valuesExpected = array(
  184. array(false, array('bürger.com', 'hãllo.com', 'hållo.com'))
  185. );
  186. foreach ($valuesExpected as $element) {
  187. foreach ($element[1] as $input) {
  188. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  189. }
  190. }
  191. // Check setting no IDN matching via constructor
  192. unset($validator);
  193. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, false);
  194. $valuesExpected = array(
  195. array(false, array('bürger.com', 'hãllo.com', 'hållo.com'))
  196. );
  197. foreach ($valuesExpected as $element) {
  198. foreach ($element[1] as $input) {
  199. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  200. }
  201. }
  202. }
  203. /**
  204. * Ensure the TLD check works as expected
  205. *
  206. */
  207. public function testTLD()
  208. {
  209. $validator = new Zend_Validate_Hostname();
  210. // Check TLD matching
  211. $valuesExpected = array(
  212. array(true, array('domain.co.uk', 'domain.uk.com', 'domain.tl', 'domain.zw', 'domain.menu')),
  213. array(false, array('domain.xx', 'domain.zz', 'domain.madeup'))
  214. );
  215. foreach ($valuesExpected as $element) {
  216. foreach ($element[1] as $input) {
  217. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  218. }
  219. }
  220. // Check no TLD matching
  221. $validator->setValidateTld(false);
  222. $valuesExpected = array(
  223. array(true, array('domain.xx', 'domain.zz', 'domain.madeup'))
  224. );
  225. foreach ($valuesExpected as $element) {
  226. foreach ($element[1] as $input) {
  227. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  228. }
  229. }
  230. // Check setting no TLD matching via constructor
  231. unset($validator);
  232. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS, true, false);
  233. $valuesExpected = array(
  234. array(true, array('domain.xx', 'domain.zz', 'domain.madeup'))
  235. );
  236. foreach ($valuesExpected as $element) {
  237. foreach ($element[1] as $input) {
  238. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  239. }
  240. }
  241. }
  242. /**
  243. * Ensures that getAllow() returns expected default value
  244. *
  245. * @return void
  246. */
  247. public function testGetAllow()
  248. {
  249. $this->assertEquals(Zend_Validate_Hostname::ALLOW_DNS, $this->_validator->getAllow());
  250. }
  251. /**
  252. * Test changed with ZF-6676, as IP check is only involved when IP patterns match
  253. *
  254. * @group ZF-2861
  255. * @group ZF-6676
  256. */
  257. public function testValidatorMessagesShouldBeTranslated()
  258. {
  259. require_once 'Zend/Translate.php';
  260. $translations = array(
  261. 'hostnameInvalidLocalName' => 'this is the IP error message',
  262. );
  263. $translator = new Zend_Translate('array', $translations);
  264. $this->_validator->setTranslator($translator);
  265. $this->_validator->isValid('0.239,512.777');
  266. $messages = $this->_validator->getMessages();
  267. $found = false;
  268. foreach ($messages as $code => $message) {
  269. if (array_key_exists($code, $translations)) {
  270. $found = true;
  271. break;
  272. }
  273. }
  274. $this->assertTrue($found);
  275. $this->assertEquals($translations[$code], $message);
  276. }
  277. /**
  278. * @group ZF-6033
  279. */
  280. public function testNumberNames()
  281. {
  282. $validator = new Zend_Validate_Hostname();
  283. // Check TLD matching
  284. $valuesExpected = array(
  285. array(true, array('www.danger1.com', 'danger.com', 'www.danger.com')),
  286. array(false, array('www.danger1com', 'dangercom', 'www.dangercom'))
  287. );
  288. foreach ($valuesExpected as $element) {
  289. foreach ($element[1] as $input) {
  290. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  291. }
  292. }
  293. }
  294. /**
  295. * @group ZF-6133
  296. */
  297. public function testPunycodeDecoding()
  298. {
  299. $validator = new Zend_Validate_Hostname();
  300. // Check TLD matching
  301. $valuesExpected = array(
  302. array(true, array('xn--brger-kva.com')),
  303. array(false, array('xn--brger-x45d2va.com', 'xn--bürger.com', 'xn--'))
  304. );
  305. foreach ($valuesExpected as $element) {
  306. foreach ($element[1] as $input) {
  307. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  308. }
  309. }
  310. }
  311. /**
  312. * @ZF-4352
  313. */
  314. public function testNonStringValidation()
  315. {
  316. $this->assertFalse($this->_validator->isValid(array(1 => 1)));
  317. }
  318. /**
  319. * @ZF-7323
  320. */
  321. public function testLatinSpecialChars()
  322. {
  323. $this->assertFalse($this->_validator->isValid('place@yah&oo.com'));
  324. $this->assertFalse($this->_validator->isValid('place@y*ahoo.com'));
  325. $this->assertFalse($this->_validator->isValid('ya#hoo'));
  326. }
  327. /**
  328. * @group ZF-7277
  329. */
  330. public function testDifferentIconvEncoding()
  331. {
  332. iconv_set_encoding('internal_encoding', 'ISO8859-1');
  333. $validator = new Zend_Validate_Hostname();
  334. $valuesExpected = array(
  335. array(true, array('bürger.com', 'hãllo.com', 'hållo.com')),
  336. array(true, array('bÜrger.com', 'hÃllo.com', 'hÅllo.com')),
  337. array(false, array('hãllo.lt', 'bürger.lt', 'hãllo.lt'))
  338. );
  339. foreach ($valuesExpected as $element) {
  340. foreach ($element[1] as $input) {
  341. $this->assertEquals($element[0], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  342. }
  343. }
  344. }
  345. /**
  346. * @ZF-8312
  347. */
  348. public function testInvalidDoubledIdn()
  349. {
  350. $this->assertFalse($this->_validator->isValid('test.com / http://www.test.com'));
  351. }
  352. /**
  353. * @group ZF-10267
  354. */
  355. public function testURI()
  356. {
  357. $valuesExpected = array(
  358. array(Zend_Validate_Hostname::ALLOW_URI, true, array('localhost', 'example.com', '~ex%20ample')),
  359. array(Zend_Validate_Hostname::ALLOW_URI, false, array('§bad', 'don?t.know', 'thisisaverylonghostnamewhichextendstwohundredfiftysixcharactersandthereforshouldnotbeallowedbythisvalidatorbecauserfc3986limitstheallowedcharacterstoalimitoftwohunderedfiftysixcharactersinsumbutifthistestwouldfailthenitshouldreturntruewhichthrowsanexceptionbytheunittest')),
  360. );
  361. foreach ($valuesExpected as $element) {
  362. $validator = new Zend_Validate_Hostname($element[0]);
  363. foreach ($element[2] as $input) {
  364. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  365. }
  366. }
  367. }
  368. /**
  369. * Ensure that a trailing "." in a local hostname is permitted
  370. *
  371. * @group ZF-6363
  372. */
  373. public function testTrailingDot()
  374. {
  375. $valuesExpected = array(
  376. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('example.', 'example.com.', '~ex%20ample.com.')),
  377. array(Zend_Validate_Hostname::ALLOW_ALL, false, array('example..',)),
  378. array(Zend_Validate_Hostname::ALLOW_ALL, true, array('1.2.3.4.')),
  379. array(Zend_Validate_Hostname::ALLOW_DNS, false, array('example..', '~ex%20ample..')),
  380. array(Zend_Validate_Hostname::ALLOW_LOCAL, true, array('example.', 'example.com.')),
  381. );
  382. foreach ($valuesExpected as $element) {
  383. $validator = new Zend_Validate_Hostname($element[0]);
  384. foreach ($element[2] as $input) {
  385. $this->assertEquals($element[1], $validator->isValid($input), implode("\n", $validator->getMessages()) . $input);
  386. }
  387. }
  388. }
  389. /**
  390. * @group ZF-11334
  391. * @see http://www.ietf.org/rfc/rfc2732.txt
  392. */
  393. public function testSupportsIpv6AddressesWhichContainHexDigitF()
  394. {
  395. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  396. $this->assertTrue($validator->isValid('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210'));
  397. $this->assertTrue($validator->isValid('1080:0:0:0:8:800:200C:417A'));
  398. $this->assertTrue($validator->isValid('3ffe:2a00:100:7031::1'));
  399. $this->assertTrue($validator->isValid('1080::8:800:200C:417A'));
  400. $this->assertTrue($validator->isValid('::192.9.5.5'));
  401. $this->assertTrue($validator->isValid('::FFFF:129.144.52.38'));
  402. $this->assertTrue($validator->isValid('2010:836B:4179::836B:4179'));
  403. }
  404. /**
  405. * @group ZF-11796
  406. */
  407. public function testIDNSI()
  408. {
  409. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  410. $this->assertTrue($validator->isValid('Test123.si'));
  411. $this->assertTrue($validator->isValid('țest123.si'));
  412. $this->assertTrue($validator->isValid('tĕst123.si'));
  413. $this->assertTrue($validator->isValid('tàrø.si'));
  414. $this->assertFalse($validator->isValid('رات.si'));
  415. }
  416. /**
  417. * @ZF-12314
  418. */
  419. public function testDKSpecialChars()
  420. {
  421. $this->assertTrue($this->_validator->isValid('testæøå.dk'));
  422. }
  423. /**
  424. * test for IDN CA
  425. */
  426. public function testIDNCA()
  427. {
  428. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  429. $this->assertTrue($validator->isValid('Test123.ca'));
  430. $this->assertTrue($validator->isValid('tàr.ca'));
  431. $this->assertFalse($validator->isValid('țest123.ca'));
  432. $this->assertFalse($validator->isValid('tĕst123.ca'));
  433. $this->assertFalse($validator->isValid('رات.ca'));
  434. }
  435. /**
  436. * @group ZF-12413
  437. */
  438. public function testIDNUA()
  439. {
  440. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  441. $this->assertTrue($validator->isValid('самобраноч.com.ua'));
  442. $this->assertTrue($validator->isValid('hostmaster.ua'));
  443. }
  444. /**
  445. * Test for IDN serbia .rs
  446. *
  447. * @group GH-115
  448. */
  449. public function testIDNRS()
  450. {
  451. $validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
  452. $this->assertTrue($validator->isValid('test.rs'));
  453. }
  454. }