?
avatar OlegKi
OlegKi
7 Oct 2017

I use <img> with srcset, where the images are loaded from cloudinary.com CDN. The HTML fragment looks like

<img style="vertical-align: middle; display: block; position: relative; margin-right: 1em; width: 60px; height: 60px; float: left;"
src="https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_60/v1506108465/Now_Certified_1067x1067_Red_qton01.png"
srcset="https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_60/v1506108465/Now_Certified_1067x1067_Red_qton01.png, 
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_72/v1506108465/Now_Certified_1067x1067_Red_qton01.png 1.2x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_90/v1506108465/Now_Certified_1067x1067_Red_qton01.png 1.5x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_120/v1506108465/Now_Certified_1067x1067_Red_qton01.png 2x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_180/v1506108465/Now_Certified_1067x1067_Red_qton01.png 3x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_240/v1506108465/Now_Certified_1067x1067_Red_qton01.png 4x"
alt="servicenow certified" width="60" height="60" />

where the srcset in short form looks like

srcset="url1, url2 1.2x, url3 2x, url4 3x, url5 4x"

It's important that there are exist at least one whitespace between URLs included. See here and here. The above example contains absolute URLs. One can insert the <img> in any Article of Joomla to be able to reproduce the reported problem.

Expected result

The <img> should load the picture from one from URLs included in srcset based on the value of dpr HTTP header sent to the server automatically by modern web browsers (for example Chrome) because of the usage of

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width" />

on the <head> of HTML page.

Actual result

The whitespaces between URLs included in srcset will be removed by version 3.8.1. I suppose that the reason is the bug is the pull request #17978. As the result, the web browser attempt to load the picture from URL: url1,url2 (https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_60/v1506108465/Now_Certified_1067x1067_Red_qton01.png,https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_72/v1506108465/Now_Certified_1067x1067_Red_qton01.png) instead of url1 and no picture will be displayed.

System information (as much as possible)

I used Chrome 61.0.3163.100 (Official Build) (64-bit) Windows mostly in my tests. Network trace of Developer Tools shows red the URLs, which will be not found. One can easy see that URL, which will be used to load the picture, is concatenation of two URLs. Developer Tools can be used to examine generated HTML code. One can see no space between URLs used in srcset. Other information about system settings:

Setting Value
PHP Built On Linux puls.metanet.ch 3.10.0-514.21.1.el7.x86_64 #1 SMP Thu May 25 17:04:51 UTC 2017 x86_64
Database Version 5.5.5-10.1.25-MariaDB
Database Collation utf8_general_ci
Database Connection Collation utf8mb4_general_ci
PHP Version 7.1.10
Web Server Apache
WebServer to PHP Interface fpm-fcgi
Joomla! Version Joomla! 3.8.0 Stable [ Amani ] 19-September-2017 14:00 GMT
Joomla! Platform Version Joomla Platform 13.1.0 Stable [ Curiosity ] 24-Apr-2013 00:00 GMT

(It was 3.8.1 after updating, but I have to downgrade the web site back to 3.8.0 to be able to display the pictures)

Additional comments

To be exactly the version 3.8 has already another problem in processing of URLs included in srcset. It inserts unneeded slashes in the URL. You can see that the srcset included above contains 6 URLs, which contains fragments /c_scale,f_auto,q_auto,w_60/, /c_scale,f_auto,q_auto,w_72/, /c_scale,f_auto,q_auto,w_90/, ... , /c_scale,f_auto,q_auto,w_240/. Joomla 3.8 modifies all URLs starting with the second one including unneeded / symbols. Joomla 3.8 modifies all URLs starting with the second one to /c_scale,f_auto,q_auto,/w_72/, /c_scale,f_auto,q_auto,/w_90/, ... , /c_scale,f_auto,q_auto,/w_240/ holding the first one (/c_scale,f_auto,q_auto,w_60/) unchanged. One can see on the page as an example that the original srcset included above will be modified to

<img style="vertical-align: middle; display: block; position: relative; margin-right: 1em; width: 60px; height: 60px; float: left;"
src="https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_60/v1506108465/Now_Certified_1067x1067_Red_qton01.png"
srcset="https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_60/v1506108465/Now_Certified_1067x1067_Red_qton01.png, 
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,/w_72/v1506108465/Now_Certified_1067x1067_Red_qton01.png 1.2x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,/w_90/v1506108465/Now_Certified_1067x1067_Red_qton01.png 1.5x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,/w_120/v1506108465/Now_Certified_1067x1067_Red_qton01.png 2x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,/w_180/v1506108465/Now_Certified_1067x1067_Red_qton01.png 3x,
https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,/w_240/v1506108465/Now_Certified_1067x1067_Red_qton01.png 4x"
alt="servicenow certified" width="60" height="60">

I suppose that the reason of the problem is the usage of explode in the line of code. The line don't take in consideration, that commas could be the part of the URLs. It's my luck, that cloudinary.com CDN resolves the modified URL and loads the same. It would be good to fix the problem too.

It could be that the main problem described at the beginning of the issue could be solved by replacing the line

return ' srcset="' . implode(",", $data) . '"';

to

return ' srcset="' . implode(", ", $data) . '"';

but, it would be better to eliminate the usage of explode in parsing of srcset values. I think that only in the way one could solve the last problem, which I reported.

avatar OlegKi OlegKi - open - 7 Oct 2017
avatar joomla-cms-bot joomla-cms-bot - change - 7 Oct 2017
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 7 Oct 2017
avatar franz-wohlkoenig franz-wohlkoenig - change - 7 Oct 2017
Category Administration
avatar OlegKi OlegKi - change - 7 Oct 2017
The description was changed
avatar OlegKi OlegKi - edited - 7 Oct 2017
avatar ggppdk
ggppdk - comment - 7 Oct 2017

@OlegKi
please test PR #18273

avatar franz-wohlkoenig franz-wohlkoenig - change - 8 Oct 2017
Status New Closed
Closed_Date 0000-00-00 00:00:00 2017-10-08 05:40:45
Closed_By franz-wohlkoenig
avatar joomla-cms-bot joomla-cms-bot - change - 8 Oct 2017
Closed_By franz-wohlkoenig joomla-cms-bot
avatar joomla-cms-bot joomla-cms-bot - close - 8 Oct 2017
avatar joomla-cms-bot
joomla-cms-bot - comment - 8 Oct 2017
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 8 Oct 2017

closed as having Pull Request #18273

avatar OlegKi
OlegKi - comment - 8 Oct 2017

@ggppdk , @franz-wohlkoenig Thank you for the PR! It solves the man problem, which I reported, but the next line of the code of sef.php is still buggy. I mean the line

foreach (explode(",", $match[1]) as $url)
{
    $data[] = preg_replace('#^(?!/|' . $protocols . '|\#|\')(.+)#', $base . '$1', trim($url));
}

The following test data could be used to reproduce the bug:

$match[1]=https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_320/v1505755918/Brightsource-banner-2120x600_eqojha.jpg, https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_640/v1505755918/Brightsource-banner-2120x600_eqojha.jpg 2x, https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_960/v1505755918/Brightsource-banner-2120x600_eqojha.jpg 3x, https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_1280/v1505755918/Brightsource-banner-2120x600_eqojha.jpg 4x

It will be parsed so that $url will have the following values in the loop:

https://res.cloudinary.com/b-rightsource/image/..._eqojha.jpg
https://res.cloudinary.com/b-rightsource/image/..._eqojha.jpg 2x
https://res.cloudinary.com/b-rightsource/image/..._eqojha.jpg 3x
https://res.cloudinary.com/b-rightsource/image/..._eqojha.jpg 4x

(I reduced the urls to make there more readable).
The expression preg_replace('#^(?!/|' . $protocols . '|\#|\')(.+)#', $base . '$1', trim($url)) don't change the first $url, but it produces wrong results if the URL is appebdex with " 2x", " 3x", " 4x".

One can use https://www.functions-online.com/preg_replace.html for example to reproduce the problem. One need to use

parameter Value
$pattern #(?!/|[a-zA-Z0-9\-]+:|\#|\')([^\s]+)\s+(.*)#
$replacement /joomla/$1 $2
$subject https://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_640/v1505755918/Brightsource-banner-2120x600_eqojha.jpg 2x
result https/joomla/://res.cloudinary.com/b-rightsource/image/upload/c_scale,f_auto,q_auto,w_640/v1505755918/Brightsource-banner-2120x600_eqojha.jpg 2x

The $pattern equal to #(?!/|[a-zA-Z0-9\-]+:|\#|\')([^\s]+)\s+(.*)#, and the $replacement as /joomla/$1 $2 (I used http://localhost/joomla/ as the root of site. $protocols=[a-zA-Z0-9\-]+:, $base=/joomla/) produces wrong results.

Add a Comment

Login with GitHub to post a comment