From c08b18c4b92cc7c253c72709e3aecb639a742d9f Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Fri, 29 Apr 2011 04:17:42 -0400
Subject: [PATCH] - Fix relative URLs handling according to a <base> in HTML (#1487889)

---
 CHANGELOG                        |    1 +
 program/include/rcube_shared.inc |    6 +++---
 tests/src/htmlbase.txt           |   10 ++++++++++
 program/steps/mail/func.inc      |   11 ++++++-----
 tests/mailfunc.php               |   12 ++++++++++++
 5 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 5182f6a..c3495cd 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix relative URLs handling according to a <base> in HTML (#1487889)
 - Fix handling of top-level domains with more than 5 chars or unicode chars (#1487883)
 - Fix usage of non-standard HTTP error codes (#1487797)
 - Improve performance by including files with absolute path (#1487849)
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index 1fd6ed0..68f3fe4 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -231,7 +231,7 @@
   }
 
   // $path is absolute
-  if ($path{0}=='/')
+  if ($path[0] == '/')
     $abs_path = $host_url.$path;
   else
   {
@@ -243,13 +243,13 @@
       {
         if (strrpos($base_url, '/'))
           $base_url = substr($base_url, 0, strrpos($base_url, '/'));
-        
+
         $path = substr($path, 3);
       }
 
     $abs_path = $base_url.'/'.$path;
   }
-    
+
   return $abs_path;
 }
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index c346ef3..0f25ec7 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -607,6 +607,7 @@
       $html = '<head></head>'. $html;
     $html = substr_replace($html, '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0);
   }
+
   // turn relative into absolute urls
   $html = rcmail_resolve_base($html);
 
@@ -955,13 +956,13 @@
 function rcmail_message_full_headers($attrib, $headers=NULL)
 {
   global $OUTPUT;
-  
+
   $html = html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('load-headers','',this)"), '');
   $html .= html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
-  
+
   $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
   $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
-  
+
   return html::div($attrib, $html);
 }
 
@@ -1086,8 +1087,8 @@
     $replacer = new rcube_base_replacer($regs[2]);
 
     // replace all relative paths
-    $body = preg_replace_callback('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body);
-    $body = preg_replace_callback('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body);
+    $body = preg_replace_callback('/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body);
+    $body = preg_replace_callback('/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body);
   }
 
   return $body;
diff --git a/tests/mailfunc.php b/tests/mailfunc.php
index 92cfbb1..9d70bef 100644
--- a/tests/mailfunc.php
+++ b/tests/mailfunc.php
@@ -145,4 +145,16 @@
     $this->assertNoPattern('|<p>test2</p>|', $washed, "Conditional HTML comments");
   }
 
+  /**
+   * Test URI base resolving in HTML messages
+   */
+  function test_resolve_base()
+  {
+    $html = file_get_contents(TESTS_DIR . 'src/htmlbase.txt');
+    $html = rcmail_resolve_base($html);
+
+    $this->assertPattern('|src="http://alec\.pl/dir/img1\.gif"|', $html, "URI base resolving [1]");
+    $this->assertPattern('|src="http://alec\.pl/dir/img2\.gif"|', $html, "URI base resolving [2]");
+    $this->assertPattern('|src="http://alec\.pl/img3\.gif"|', $html, "URI base resolving [3]");
+  }
 }
diff --git a/tests/src/htmlbase.txt b/tests/src/htmlbase.txt
new file mode 100644
index 0000000..d1ddd54
--- /dev/null
+++ b/tests/src/htmlbase.txt
@@ -0,0 +1,10 @@
+<html>
+<head>
+<base href="http://alec.pl/dir/" />
+</head>
+<body>
+<img src="img1.gif" />
+<img src="./img2.gif" />
+<img src="../img3.gif" />
+</body>
+</html>

--
Gitblit v1.9.1