IPv6.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. /**
  3. * Validates an IPv6 address.
  4. * @author Feyd @ forums.devnetwork.net (public domain)
  5. * @note This function requires brackets to have been removed from address
  6. * in URI.
  7. */
  8. class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
  9. {
  10. /**
  11. * @param string $aIP
  12. * @param HTMLPurifier_Config $config
  13. * @param HTMLPurifier_Context $context
  14. * @return bool|string
  15. */
  16. public function validate($aIP, $config, $context)
  17. {
  18. if (!$this->ip4) {
  19. $this->_loadRegex();
  20. }
  21. $original = $aIP;
  22. $hex = '[0-9a-fA-F]';
  23. $blk = '(?:' . $hex . '{1,4})';
  24. $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128
  25. // prefix check
  26. if (strpos($aIP, '/') !== false) {
  27. if (preg_match('#' . $pre . '$#s', $aIP, $find)) {
  28. $aIP = substr($aIP, 0, 0 - strlen($find[0]));
  29. unset($find);
  30. } else {
  31. return false;
  32. }
  33. }
  34. // IPv4-compatiblity check
  35. if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) {
  36. $aIP = substr($aIP, 0, 0 - strlen($find[0]));
  37. $ip = explode('.', $find[0]);
  38. $ip = array_map('dechex', $ip);
  39. $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3];
  40. unset($find, $ip);
  41. }
  42. // compression check
  43. $aIP = explode('::', $aIP);
  44. $c = count($aIP);
  45. if ($c > 2) {
  46. return false;
  47. } elseif ($c == 2) {
  48. list($first, $second) = $aIP;
  49. $first = explode(':', $first);
  50. $second = explode(':', $second);
  51. if (count($first) + count($second) > 8) {
  52. return false;
  53. }
  54. while (count($first) < 8) {
  55. array_push($first, '0');
  56. }
  57. array_splice($first, 8 - count($second), 8, $second);
  58. $aIP = $first;
  59. unset($first, $second);
  60. } else {
  61. $aIP = explode(':', $aIP[0]);
  62. }
  63. $c = count($aIP);
  64. if ($c != 8) {
  65. return false;
  66. }
  67. // All the pieces should be 16-bit hex strings. Are they?
  68. foreach ($aIP as $piece) {
  69. if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) {
  70. return false;
  71. }
  72. }
  73. return $original;
  74. }
  75. }
  76. // vim: et sw=4 sts=4