diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index dfc3137f76..95e71e45fc 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -80,7 +80,8 @@ class HashedFilesMixin: ( "*.css", ( - r"""(?Purl\(['"]{0,1}\s*(?P.*?)["']{0,1}\))""", + r"""(?Purl\((?P['"]{0,1})""" + r"""\s*(?P.*?)(?P=quote)\))""", ( r"""(?P@import\s*["']\s*(?P.*?)["'])""", """@import url("%(url)s")""", diff --git a/tests/staticfiles_tests/project/documents/cached/data_uri_with_nested_url.css b/tests/staticfiles_tests/project/documents/cached/data_uri_with_nested_url.css new file mode 100644 index 0000000000..86e64e9498 --- /dev/null +++ b/tests/staticfiles_tests/project/documents/cached/data_uri_with_nested_url.css @@ -0,0 +1,3 @@ +#example { + background-image: url("data:image/svg+xml,url(%23b) url(%23c)"); +} diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index 9ca4d62553..35799f0ff7 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -235,6 +235,13 @@ class TestHashedFiles: self.assertIn(b"other.d41d8cd98f00.css", content) self.assertPostCondition() + def test_css_data_uri_with_nested_url(self): + relpath = self.hashed_file_path("cached/data_uri_with_nested_url.css") + with storage.staticfiles_storage.open(relpath) as relfile: + content = relfile.read() + self.assertIn(b'url("data:image/svg+xml,url(%23b) url(%23c)")', content) + self.assertPostCondition() + def test_css_source_map(self): relpath = self.hashed_file_path("cached/source_map.css") self.assertEqual(relpath, "cached/source_map.b2fceaf426aa.css")