diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 7ba18706510..097a0e9a18a 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -1962,6 +1962,7 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
$tmparrayoftags = explode(',', $noescapetags);
}
if (count($tmparrayoftags)) {
+ $reg = array();
$tmp = str_ireplace('__DOUBLEQUOTE', '', $tmp); // The keyword DOUBLEQUOTE is forbidden. Reserved, so we removed it if we find it.
foreach ($tmparrayoftags as $tagtoreplace) {
@@ -1970,30 +1971,37 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
$tmp = preg_replace('/<'.preg_quote($tagtoreplace, '/').' \/>/', '__BEGINENDTAGTOREPLACE'.$tagtoreplace.'__', $tmp);
// For case of tag with attribute
- $reg = array();
- if (preg_match('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+)>/', $tmp, $reg)) {
- $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[1]); // We must never have [ ] inside the attribute string
- $tmpattributes = str_ireplace('href="http:', '__HREFHTTPA', $tmpattributes);
- $tmpattributes = str_ireplace('href="https:', '__HREFHTTPSA', $tmpattributes);
- $tmpattributes = str_ireplace('src="http:', '__SRCHTTPIMG', $tmpattributes);
- $tmpattributes = str_ireplace('src="https:', '__SRCHTTPSIMG', $tmpattributes);
- $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes);
- $tmpattributes = preg_replace('/[^a-z0-9_\/\?\;:\s=&\.-]/i', '', $tmpattributes);
- //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must avoid escaping but not remove content
- $tmp = preg_replace('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+)>/', '__BEGINTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp);
- }
- if (preg_match('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+)> \/>/', $tmp, $reg)) {
- $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[1]); // We must not have [ ] inside the attribute string
- $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes);
- $tmpattributes = preg_replace('/[^a-z0-9_\/\?\;:\s=&]/i', '', $tmpattributes);
- //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must avoid escaping but not remove content
- $tmp = preg_replace('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+) \/>/', '__BEGINENDTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp);
- }
+ do {
+ $tmpold = $tmp;
+
+ if (preg_match('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+)>/', $tmp, $reg)) {
+ $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[1]); // We must never have [ ] inside the attribute string
+ $tmpattributes = str_ireplace('href="http:', '__HREFHTTPA', $tmpattributes);
+ $tmpattributes = str_ireplace('href="https:', '__HREFHTTPSA', $tmpattributes);
+ $tmpattributes = str_ireplace('src="http:', '__SRCHTTPIMG', $tmpattributes);
+ $tmpattributes = str_ireplace('src="https:', '__SRCHTTPSIMG', $tmpattributes);
+ $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes);
+ $tmpattributes = preg_replace('/[^a-z0-9_\/\?\;\s=&\.\-@:\.#\+]/i', '', $tmpattributes);
+ //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must not remove content
+ $tmp = preg_replace('/<'.preg_quote($tagtoreplace, '/').'\s+'.preg_quote($reg[1], '/').'>/', '__BEGINTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp);
+ }
+ if (preg_match('/<'.preg_quote($tagtoreplace, '/').'\s+([^>]+)\s+\/>/', $tmp, $reg)) {
+ $tmpattributes = str_ireplace(array('[', ']'), '_', $reg[1]); // We must not have [ ] inside the attribute string
+ $tmpattributes = str_ireplace('"', '__DOUBLEQUOTE', $tmpattributes);
+ $tmpattributes = preg_replace('/[^a-z0-9_\/\?\;\s=&\.\-@:\.#\+]/i', '', $tmpattributes);
+ //$tmpattributes = preg_replace("/float:\s*(left|right)/", "", $tmpattributes); // Disabled: we must not remove content.
+ $tmp = preg_replace('/<'.preg_quote($tagtoreplace, '/').'\s+'.preg_quote($reg[1], '/').'\s+\/>/', '__BEGINENDTAGTOREPLACE'.$tagtoreplace.'['.$tmpattributes.']__', $tmp);
+ }
+
+ $diff = strcmp($tmpold, $tmp);
+ } while ($diff);
}
}
$result = htmlentities($tmp, ENT_COMPAT, 'UTF-8'); // Convert & into & and more...
+ //print $result;
+
if (count($tmparrayoftags)) {
foreach ($tmparrayoftags as $tagtoreplace) {
$result = str_ireplace('__BEGINTAGTOREPLACE'.$tagtoreplace.'__', '<'.$tagtoreplace.'>', $result);
diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php
index 419db999be2..07c5f1e88f1 100644
--- a/test/phpunit/FunctionsLibTest.php
+++ b/test/phpunit/FunctionsLibTest.php
@@ -1106,10 +1106,10 @@ class FunctionsLibTest extends CommonClassTest
/**
- * testDolEscapeHtmlTag
- *
- * @return void
- */
+ * testDolEscapeHtmlTag
+ *
+ * @return void
+ */
public function testDolEscapeHtmlTag()
{
$input = 'x&#,"'; // & and " are converted into html entities, are removed
@@ -1123,6 +1123,18 @@ class FunctionsLibTest extends CommonClassTest
$input = '
'; // & and " are converted into html entities, are not removed
$result = dol_escape_htmltag($input, 1, 1, 'common', 0, 1);
$this->assertEquals('
', $result);
+
+
+ $input = '
+

+
+ ';
+
+ $result = dol_escape_htmltag($input, 1, 1, 'common');
+ $this->assertEquals($input, $result);
}