--- /tmp/link/link.module	2009-11-09 03:02:12.000000000 +0100
+++ link.module	2009-12-17 13:42:09.000000000 +0100
@@ -11,6 +11,20 @@ define('LINK_INTERNAL', 'internal');
 define('LINK_FRONT', 'front');
 define('LINK_EMAIL', 'email');
 define('LINK_DOMAINS', 'aero|arpa|asia|biz|com|cat|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|mobi|local');
+define('LINK_ICHARS', (string) html_entity_decode(implode("", array(
+    "&#x00E6;", // æ
+    "&#x00C6;", // Æ
+    "&#x00F8;", // ø
+    "&#x00D8;", // Ø
+    "&#x00E5;", // å
+    "&#x00C5;", // Å
+    "&#x00E4;", // ä
+    "&#x00C4;", // Ä
+    "&#x00F6;", // ö
+    "&#x00D6;", // Ö
+    "&#x00FC;", // ü
+    "&#x00DC;", // Ü
+  )), ENT_QUOTES, 'UTF-8'));
 
 define('LINK_TARGET_DEFAULT', 'default');
 define('LINK_TARGET_NEW_WINDOW', '_blank');
@@ -690,12 +704,11 @@ function link_cleanup_url($url, $protoco
  * the following attributes: protocol, hostname, ip, and port.
  */
 function link_validate_url($text) {
-
   $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
 
   $protocol = '(('. implode("|", $allowed_protocols) .'):\/\/)';
-  $authentication = '([a-z0-9]+(:[a-z0-9]+)?@)';
-  $domain = '(([a-z0-9]([a-z0-9\-_\[\]])*)(\.(([a-z0-9\-_\[\]])+\.)*('. LINK_DOMAINS .'|[a-z]{2}))?)';
+  $authentication = '([a-z0-9' . LINK_ICHARS . ']+(:[a-z0-9'. LINK_ICHARS . ']+)?@)';
+  $domain = '(([a-z0-9' . LINK_ICHARS . ']([a-z0-9'. LINK_ICHARS . '\-_\[\]])*)(\.(([a-z0-9' . LINK_ICHARS . '\-_\[\]])+\.)*('. LINK_DOMAINS .'|[a-z]{2}))?)';
   $ipv4 = '([0-9]{1,3}(\.[0-9]{1,3}){3})';
   $ipv6 = '([0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7})';
   $port = '(:([0-9]{1,5}))';
@@ -704,17 +717,17 @@ function link_validate_url($text) {
   $external_pattern = '/^'. $protocol .'?'. $authentication .'?('. $domain .'|'. $ipv4 .'|'. $ipv6 .' |localhost)'. $port .'?';
 
   // Pattern specific to internal links.
-  $internal_pattern = "/^([a-z0-9_\-+\[\]]+)";
+  $internal_pattern = "/^([a-z0-9" . LINK_ICHARS . "_\-+\[\]]+)";
 
-  $directories = "(\/[a-z0-9_\-\.~+%=&,$'!():;*@\[\]]*)*";
+  $directories = "(\/[a-z0-9" . LINK_ICHARS . "_\-\.~+%=&,$'!():;*@\[\]]*)*";
   // Yes, four backslashes == a single backslash.
-  $query = "(\/?\?([?a-z0-9+_|\-\.\/\\\\%=&,$'():;*@\[\]]*))";
-  $anchor = "(#[a-z0-9_\-\.~+%=&,$'():;*@\[\]]*)";
+  $query = "(\/?\?([?a-z0-9". LINK_ICHARS ."+_|\-\.\/\\\\%=&,$'():;*@\[\]]*))";
+  $anchor = "(#[a-z0-9" . LINK_ICHARS . "_\-\.~+%=&,$'():;*@\[\]]*)";
 
   // The rest of the path for a standard URL.
   $end = $directories .'?'. $query .'?'. $anchor .'?'.'$/i';
 
-  $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
+  $user = '[a-zA-Z0-9' . LINK_ICHARS . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+';
   $email_pattern = '/^mailto:'. $user .'@'.'('. $domain .'|'. $ipv4 .'|'. $ipv6 .'|localhost)'. $query .'?$/';
 
   if (strpos($text, '<front>') === 0) {
