According to the CSS spec at http://www.w3.org/TR/CSS21/syndata.html#uri, the url() property can include whitespace before and after the URI. The regular expression in drupal_build_css_cache() needs to be modified to take this into account. Otherwise, images included in some CSS files do not get their paths corrected according to the aggregated CSS file's location.

See the attached patch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lilou’s picture

Status: Needs review » Closed (duplicate)
Gribnif’s picture

Status: Closed (duplicate) » Needs review

Please re-read the description. This is a separate issue from #289293: CSS Aggregation: regexp mangles URL's in CSS. That one has to do with path elements containing exactly two-characters. The bug described above has to do with spaces before and after the URI.

I did report the same problem as that other issue, but it was in #255293: Incorrect regexp causes some aggregated CSS refs to fail.

Anonymous’s picture

Yes, definitely a different issue. The patch looks good but I need to test it.

Anonymous’s picture

Status: Needs review » Needs work

Speaking of testing, can you provide a simpletest for this? We need to not break it in the future.

hass’s picture

subscribe

hass’s picture

Color module is missing in the patch.

kscheirer’s picture

I'm not sure how we would test this. I guess there needs to be a dummy simpletest.css file that has urls with leading and trailing whitespace. Then execute drupal_build_css_cache() and check the resulting file for the correct paths?

Or we could store the regular expression as a variable or constant, and write a check against it directly using $this->assertPattern()?

casey’s picture

Issue tags: +CSS aggregation

tagging

casey’s picture

Status: Needs work » Needs review
FileSize
1.69 KB
c960657’s picture

-  $contents = preg_replace_callback('/@import\s*(?:url\()?[\'"]?(?![a-z]+:)([^\'"\()]+)[\'"]?\)?;/', '_drupal_load_stylesheet', $contents);
+  $contents = preg_replace_callback('/@import\s*(?:url\()?\s*[\'"]?(?![a-z]+:)([^\'"\()]+)[\'"]?\s*\)?;/', '_drupal_load_stylesheet', $contents);

White-space is also allowed before the trailing semicolon.
A minor nit: I suggest moving the first new \s* into the parenthesis to prevent unnecessary backtracking caused by the two battling \s* when there is no url( prefix, i.e. like this:

-  $contents = preg_replace_callback('/@import\s*(?:url\()?[\'"]? ...
+  $contents = preg_replace_callback('/@import\s*(?:url\(\s)?*[\'"]? ...
-  return preg_replace('/url\(([\'"]?)(?![a-z]+:)([^\'")]+)[\'"]?\)?;/i', 'url(\1' . dirname($filename) . '/', $file);
+  return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:)([^\'")]+)[\'"]?\s*\)?;/i', 'url(\1' . dirname($filename) . '/', $file);

White-space is also allowed here before the trailing semicolon.

Apart from that, it looks good.

Looks like some tests are much needed. There is already one CSS aggregation test in modules/simpletest/tests/common.test.

casey’s picture

Assigned: Unassigned » casey
Status: Needs review » Needs work

hmmm patch is still pretty broken.

casey’s picture

Status: Needs work » Needs review
FileSize
1.76 KB

Reroll with suggestions from c960657.

jhedstrom’s picture

Subscribing

hargobind’s picture

subscribing

casey’s picture

FileSize
1.65 KB

Reroll

casey’s picture

FileSize
2.04 KB

Reroll

rfay’s picture

Note that both items in #18 were D6 issues.

andypost’s picture

casey’s picture

FileSize
1.65 KB

Reroll. Can we get a RTBC here? This patch is so obvious.

@andypost, that patch is about something else.

andypost’s picture

Last hunk seems removes ability to have space between url and (

casey’s picture

That is how it is supposed to be; http://www.w3.org/TR/CSS21/syndata.html#uri

andypost’s picture

So it's looks fine except no tests. Could you extend a test from modules/simpletest/tests/common.test
within CascadingStylesheetsUnitTest class

casey’s picture

What should the test contain? whether an invalid url() in a stylesheet is skipped when being preprocessed? I am not sure this needs a test.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

I reviewed this again and see no reason to write a test for this preg so RTBC

casey’s picture

Still applies

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

andypost’s picture

Version: 7.x-dev » 6.x-dev
Status: Fixed » Patch (to be ported)

@casey, Please, re-roll this for D6

ridgerunner’s picture

Version: 6.x-dev » 7.x-dev
Status: Patch (to be ported) » Needs review
FileSize
2.69 KB

All three regexes of the recently committed patch do not work correctly. They all now erroneously match absolute and external URLs if they are unquoted and have leading whitespace. Looking at the first of the three regexes, here is an example of what happens when drupal_build_css_cache() processes susceptible external and absolute URLs:

Given:
$base_path = 'basepath/';
$latest_regex = '/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i';

Before drupal_build_css_cache():
url( http://example.com/path/filename.txt );
url( /path/filename.txt );

After drupal_build_css_cache():
url(basepath/ http://example.com/path/filename.txt );
url(basepath/ /path/filename.txt );

The erroneous match happens because the \s* expression is able to give up one of its spaces to allow the negative lookahead to incorrectly match absolute and external URLs (at a position one space back from where the URL string actually starts). This problem is easily fixed for this particular regex by adding a possessive + to the first \s* expression.

The attached patch possessifies the \s* and all other applicable quantifiers to both fix the above mentioned bug and to improve efficiency (especially for non-matches). This patch also fixes another nasty bug (in the last regex in drupal_load_stylesheet_content()) where @imports having absolute URLs (which should be ignored and left alone) were instead being matched and then effectively deleted. This patch also adds the whitespace fix to the identical URL matching regex in the color module which was overlooked by the previous patch.

andypost’s picture

It seems reasonable I've not tested previous patch with baseurl.

@ridgerunner How can I help to test this?

kscheirer’s picture

Status: Needs review » Needs work

seems like we should roll back this commit and then get some tests in place with a new patch.

andypost’s picture

Suppose a follow-up is enough

Wim Leers’s picture

Status: Needs work » Closed (fixed)
Issue tags: -Needs backport to D6

Setting back to state of commit at #28. Please open a new issue if there is still a bug.

The problems indicated in #30 are only possible because #21 got committed without additional test coverage. Sad. But still, please open a new issue. It's been sitting here for almost 3 years because it's so hard to find.