If you have a huge page which contains lot of HTML tags, probably your site will be slow, throw error for pcre.backtrack_limit
or hang. These problems come from the following regexp which has serious impact on performance:
// Replace all unknown protocols in CSS background image.
if (strpos($buffer, 'style=') !== false)
{
$regex_url = '\s*url\s*\(([\'\"]|\&\#0?3[49];)?(?!/|\&\#0?3[49];|' . $protocols . '|\#)([^\)\'\"]+)([\'\"]|\&\#0?3[49];)?\)';
$regex = '#style=\s*([\'\"])(.*):' . $regex_url . '#m';
$buffer = preg_replace($regex, 'style=$1$2: url($3' . $base . '$4$5)', $buffer);
$this->checkBuffer($buffer);
}
The description of this part is not so good, I think. In real this part fixes the relative url's in the style attributes url(). Example: http://codepad.org/bIUgVuSw
On my test system, ~1000 div needed 1sec to run this regexp.
Div count | ms |
---|---|
100 | 20 |
300 | 100 |
600 | 350 |
1000 | 1000 |
2000 | 4000 |
3000 | 9000 |
4000 | 16000 |
<?php
$protocols = '[a-zA-Z0-9\-]+:';
$regex_url = '\s*url\s*\(([\'\"]|\&\#0?3[49];)?(?!/|\&\#0?3[49];|' . $protocols . '|\#)([^\)\'\"]+)([\'\"]|\&\#0?3[49];)?\)';
$regex = '#style=\s*([\'\"])(.*):' . $regex_url . '#m';
$base = 'https://mybase.com/';
$buffer = '';
for ($i = 0; $i < 1030; $i++) {
$buffer .= '<div style="background-image: url(\'http://test.com/picture.jpg\')">' . $i . '</div>';
}
$buffer = preg_replace($regex, 'style=$1$2: url($3' . $base . '$4$5)', $buffer);
echo $buffer;
The problem happens only when the style attribute does not have anything to match. I tries to combine non matched string parts to find a possible match.
In the original version, the regexp matches everything until it finds a :
character. So instead using a plain wildcard, it would be better to match every character until a HTML tag close character found [^>]
.
Original:
$regex = '#style=\s*([\'\"])(.*):' . $regex_url . '#m';
Updated:
$regex = '#style=\s*(['"])([^>]*):' . $regex_url . '#m';
Div count | ms |
---|---|
100 | 7 |
300 | 9 |
600 | 10 |
1000 | 13 |
2000 | 15 |
3000 | 20 |
4000 | 20 |
10000 | 50 |
<?php
$protocols = '[a-zA-Z0-9\-]+:';
$regex_url = '\s*url\s*\(([\'\"]|\&\#0?3[49];)?(?!/|\&\#0?3[49];|' . $protocols . '|\#)([^\)\'\"]+)([\'\"]|\&\#0?3[49];)?\)';
$regex = '#style=\s*([\'\"])([^>]*):' . $regex_url . '#m';
$base = 'https://mybase.com/';
$buffer = '';
for ($i = 0; $i < 4000; $i++) {
$buffer .= '<div style="background-image: url(\'/picture.jpg\');">' . $i . '</div>';
}
echo preg_replace($regex, 'style=$1$2: url($3' . $base . '$4$5)', $buffer);
Labels |
Added:
?
|
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2019-01-15 13:09:23 |
Closed_By | ⇒ | Quy |
Closed_By | Quy | ⇒ | joomla-cms-bot |
See PR #23549
See PR #23549
Set to "closed" on behalf of @Quy by The JTracker Application at issues.joomla.org/joomla-cms/23548