diff options
| author | alecpl <alec@alec.pl> | 2011-01-10 13:22:45 +0000 | 
|---|---|---|
| committer | alecpl <alec@alec.pl> | 2011-01-10 13:22:45 +0000 | 
| commit | 0ff554d1654cecc15472de186bdcd30fb1dffc77 (patch) | |
| tree | 1d349c8abd195cdbfba9e752e0e4630c340f551d | |
| parent | 57e38f47af2526aee3e1ef01991dd7d1ebb46f24 (diff) | |
- Fix handling square brackets in links (#1487672)
| -rw-r--r-- | CHANGELOG | 1 | ||||
| -rw-r--r-- | program/include/rcube_string_replacer.php | 60 | ||||
| -rw-r--r-- | tests/mailfunc.php | 3 | ||||
| -rw-r--r-- | tests/src/plainbody.txt | 1 | 
4 files changed, 55 insertions, 10 deletions
| @@ -10,6 +10,7 @@ CHANGELOG Roundcube Webmail  - Fix namespaces handling (#1487649)  - Add handling of multifolder METADATA/ANNOTATION responses  - Fix handling of INBOX when personal namespace prefix is non-empty (#1487657) +- Fix handling square brackets in links (#1487672)  RELEASE 0.5-RC  -------------- diff --git a/program/include/rcube_string_replacer.php b/program/include/rcube_string_replacer.php index e219f3083..e0a736462 100644 --- a/program/include/rcube_string_replacer.php +++ b/program/include/rcube_string_replacer.php @@ -37,7 +37,7 @@ class rcube_string_replacer    {      // Simplified domain expression for UTF8 characters handling      $utf_domain = '[^?&@"\'\\/()\s\r\t\n]+\\.[a-z]{2,5}'; -    $url = '[a-z0-9%=#@+?.:;&\\/_~-]+'; +    $url = '[a-z0-9%=#@+?.:;&\\/_~\\[\\]-]+';      $this->link_pattern = "/([\w]+:\/\/|\Wwww\.)($utf_domain($url)?)/i";      $this->mailto_pattern = "/(" @@ -81,13 +81,19 @@ class rcube_string_replacer      if (preg_match('!^(http|ftp|file)s?://!', $scheme)) {        $url = $matches[1] . $matches[2]; -      $i = $this->add(html::a(array('href' => $url, 'target' => '_blank'), Q($url)));      }      else if (preg_match('/^(\W)www\.$/', $matches[1], $m)) { -      $url = 'www.' . $matches[2]; -      $i = $this->add($m[1] . html::a(array('href' => 'http://' . $url, 'target' => '_blank'), Q($url))); +      $url        = 'www.' . $matches[2]; +      $url_prefix = 'http://'; +      $prefix     = $m[1];      } +    $suffix = $this->parse_url_brackets($url); +    $i = $this->add($prefix . html::a(array( +      'href' => $url_prefix . $url, +      'target' => '_blank' +      ), Q($url)) . $suffix); +      // Return valid link for recognized schemes, otherwise, return the unmodified string for unrecognized schemes.      return $i >= 0 ? $this->get_replacement($i) : $matches[0];    } @@ -100,11 +106,13 @@ class rcube_string_replacer     */    public function mailto_callback($matches)    { +    $href   = $matches[1]; +    $suffix = $this->parse_url_brackets($href); +      $i = $this->add(html::a(array( -        'href' => 'mailto:' . $matches[1], -        'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".JQ($matches[1])."',this)", -      ), -      Q($matches[1]))); +        'href' => 'mailto:' . $href, +        'onclick' => "return ".JS_OBJECT_NAME.".command('compose','".JQ($href)."',this)", +      ), Q($href)) . $suffix);      return $i >= 0 ? $this->get_replacement($i) : '';    } @@ -129,4 +137,38 @@ class rcube_string_replacer      return preg_replace_callback(self::$pattern, array($this, 'replace_callback'), $str);    } -}
\ No newline at end of file +  /** +   * Fixes bracket characters in URL handling +   */ +  public static function parse_url_brackets(&$url) +  { +    // #1487672: special handling of square brackets, +    // URL regexp allows [] characters in URL, for example: +    // "http://example.com/?a[b]=c". However we need to handle +    // properly situation when a bracket is placed at the end +    // of the link e.g. "[http://example.com]" +    if (preg_match('/(\\[|\\])/', $url)) { +      $in = false; +      for ($i=0, $len=strlen($url); $i<$len; $i++) { +        if ($url[$i] == '[') { +          if ($in) +            break; +          $in = true; +        } +        else if ($url[$i] == ']') { +          if (!$in) +            break; +          $in = false; +        } +      } + +      if ($i<$len) { +        $suffix = substr($url, $i); +        $url    = substr($url, 0, $i); +      } +    } + +    return $suffix; +  } + +} diff --git a/tests/mailfunc.php b/tests/mailfunc.php index 4ba35052a..eb724b6ca 100644 --- a/tests/mailfunc.php +++ b/tests/mailfunc.php @@ -110,9 +110,10 @@ class rcube_test_mailfunc extends UnitTestCase      $part->ctype_secondary = 'plain';      $part->body = quoted_printable_decode(file_get_contents(TESTS_DIR . 'src/plainbody.txt'));      $html = rcmail_print_body($part, array('safe' => true)); -     +      $this->assertPattern('/<a href="mailto:nobody@roundcube.net" onclick="return rcmail.command\(\'compose\',\'nobody@roundcube.net\',this\)">nobody@roundcube.net<\/a>/', $html, "Mailto links with onclick");      $this->assertPattern('#<a href="http://www.apple.com/legal/privacy/" target="_blank">http://www.apple.com/legal/privacy/</a>#', $html, "Links with target=_blank"); +    $this->assertPattern('#\\[<a href="http://example.com/\\?tx\\[a\\]=5" target="_blank">http://example.com/\\?tx\\[a\\]=5</a>\\]#', $html, "Links with square brackets");    }    /** diff --git a/tests/src/plainbody.txt b/tests/src/plainbody.txt index 7ebfe429b..5d391f508 100644 --- a/tests/src/plainbody.txt +++ b/tests/src/plainbody.txt @@ -35,3 +35,4 @@ http://www.apple.com/legal/privacy/  My Info  https://myinfo.apple.com/cgi-bin/WebObjects/MyInfo +-[http://example.com/?tx[a]=5]- | 
