We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
CSS bundles generation breaks background images relative urls
This is a bug related to PR #1300.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/resources/browser/combine.py`
Content:
```
1 import re
2 from zExceptions import NotFound
3 from Acquisition import aq_base
4 from datetime import datetime
5 from plone.registry.interfaces import IRegistry
6 from plone.resource.file import FilesystemFile
7 from plone.resource.interfaces import IResourceDirectory
8 from Products.CMFPlone.interfaces import IBundleRegistry
9 from Products.CMFPlone.interfaces.resources import (
10     OVERRIDE_RESOURCE_DIRECTORY_NAME,
11 )
12 from StringIO import StringIO
13 from zope.component import getUtility
14 from zope.component import queryUtility
15 
16 PRODUCTION_RESOURCE_DIRECTORY = "production"
17 
18 
19 def get_production_resource_directory():
20     persistent_directory = queryUtility(IResourceDirectory, name="persistent")
21     if persistent_directory is None:
22         return ''
23     container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
24     try:
25         production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
26     except NotFound:
27         return "%s/++unique++1" % PRODUCTION_RESOURCE_DIRECTORY
28     timestamp = production_folder.readFile('timestamp.txt')
29     return "%s/++unique++%s" % (
30         PRODUCTION_RESOURCE_DIRECTORY, timestamp)
31 
32 
33 def get_resource(context, path):
34     if path.startswith('++plone++'):
35         # ++plone++ resources can be customized, we return their override
36         # value if any
37         overrides = get_override_directory(context)
38         filepath = path[9:]
39         if overrides.isFile(filepath):
40             return overrides.readFile(filepath)
41 
42     resource = context.unrestrictedTraverse(path)
43     if isinstance(resource, FilesystemFile):
44         (directory, sep, filename) = path.rpartition('/')
45         return context.unrestrictedTraverse(directory).readFile(filename)
46     else:
47         if hasattr(aq_base(resource), 'GET'):
48             # for FileResource
49             return resource.GET()
50         else:
51             # any BrowserView
52             return resource()
53 
54 
55 def write_js(context, folder, meta_bundle):
56     registry = getUtility(IRegistry)
57     resources = []
58 
59     # default resources
60     if meta_bundle == 'default' and registry.records.get(
61         'plone.resources/jquery.js'
62     ):
63         resources.append(get_resource(context,
64             registry.records['plone.resources/jquery.js'].value))
65         resources.append(get_resource(context,
66             registry.records['plone.resources.requirejs'].value))
67         resources.append(get_resource(context,
68             registry.records['plone.resources.configjs'].value))
69 
70     # bundles
71     bundles = registry.collectionOfInterface(
72         IBundleRegistry, prefix="plone.bundles", check=False)
73     for bundle in bundles.values():
74         if bundle.merge_with == meta_bundle and bundle.jscompilation:
75             resources.append(get_resource(context, bundle.jscompilation))
76 
77     fi = StringIO()
78     for script in resources:
79         fi.write(script + '\n')
80     folder.writeFile(meta_bundle + ".js", fi)
81 
82 
83 def write_css(context, folder, meta_bundle):
84     registry = getUtility(IRegistry)
85     resources = []
86 
87     bundles = registry.collectionOfInterface(
88         IBundleRegistry, prefix="plone.bundles", check=False)
89     for bundle in bundles.values():
90         if bundle.merge_with == meta_bundle and bundle.csscompilation:
91             css = get_resource(context, bundle.csscompilation)
92             # Preserve relative urls:
93             # we prefix with '../'' any url not starting with '/'
94             # or http: or data:
95             css = re.sub(
96                 r"""(url\(['"]?(?!['"]?([a-z]+:|\/)))""",
97                 r'\1../',
98                 css)
99             resources.append(css)
100 
101     fi = StringIO()
102     for script in resources:
103         fi.write(script + '\n')
104     folder.writeFile(meta_bundle + ".css", fi)
105 
106 
107 def get_override_directory(context):
108     persistent_directory = queryUtility(IResourceDirectory, name="persistent")
109     if persistent_directory is None:
110         return
111     if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:
112         persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)
113     return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
114 
115 
116 def combine_bundles(context):
117     container = get_override_directory(context)
118     if PRODUCTION_RESOURCE_DIRECTORY not in container:
119         container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)
120     production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
121 
122     # store timestamp
123     fi = StringIO()
124     fi.write(datetime.now().isoformat())
125     production_folder.writeFile("timestamp.txt", fi)
126 
127     # generate new combined bundles
128     write_js(context, production_folder, 'default')
129     write_js(context, production_folder, 'logged-in')
130     write_css(context, production_folder, 'default')
131     write_css(context, production_folder, 'logged-in')
132
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/resources/browser/combine.py b/Products/CMFPlone/resources/browser/combine.py
--- a/Products/CMFPlone/resources/browser/combine.py
+++ b/Products/CMFPlone/resources/browser/combine.py
@@ -89,12 +89,13 @@
     for bundle in bundles.values():
         if bundle.merge_with == meta_bundle and bundle.csscompilation:
             css = get_resource(context, bundle.csscompilation)
-            # Preserve relative urls:
-            # we prefix with '../'' any url not starting with '/'
-            # or http: or data:
+            (path, sep, filename) = bundle.csscompilation.rpartition('/')
+            # Process relative urls:
+            # we prefix with current resource path any url not starting with
+            # '/' or http: or data:
             css = re.sub(
                 r"""(url\(['"]?(?!['"]?([a-z]+:|\/)))""",
-                r'\1../',
+                r'\1%s/' % path,
                 css)
             resources.append(css)

{"golden_diff": "diff --git a/Products/CMFPlone/resources/browser/combine.py b/Products/CMFPlone/resources/browser/combine.py\n--- a/Products/CMFPlone/resources/browser/combine.py\n+++ b/Products/CMFPlone/resources/browser/combine.py\n@@ -89,12 +89,13 @@\n     for bundle in bundles.values():\n         if bundle.merge_with == meta_bundle and bundle.csscompilation:\n             css = get_resource(context, bundle.csscompilation)\n-            # Preserve relative urls:\n-            # we prefix with '../'' any url not starting with '/'\n-            # or http: or data:\n+            (path, sep, filename) = bundle.csscompilation.rpartition('/')\n+            # Process relative urls:\n+            # we prefix with current resource path any url not starting with\n+            # '/' or http: or data:\n             css = re.sub(\n                 r\"\"\"(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))\"\"\",\n-                r'\\1../',\n+                r'\\1%s/' % path,\n                 css)\n             resources.append(css)\n", "issue": "CSS bundles generation breaks background images relative urls\nThis is a bug related to PR #1300.\n\n", "before_files": [{"content": "import re\nfrom zExceptions import NotFound\nfrom Acquisition import aq_base\nfrom datetime import datetime\nfrom plone.registry.interfaces import IRegistry\nfrom plone.resource.file import FilesystemFile\nfrom plone.resource.interfaces import IResourceDirectory\nfrom Products.CMFPlone.interfaces import IBundleRegistry\nfrom Products.CMFPlone.interfaces.resources import (\n    OVERRIDE_RESOURCE_DIRECTORY_NAME,\n)\nfrom StringIO import StringIO\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nPRODUCTION_RESOURCE_DIRECTORY = \"production\"\n\n\ndef get_production_resource_directory():\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return ''\n    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n    try:\n        production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n    except NotFound:\n        return \"%s/++unique++1\" % PRODUCTION_RESOURCE_DIRECTORY\n    timestamp = production_folder.readFile('timestamp.txt')\n    return \"%s/++unique++%s\" % (\n        PRODUCTION_RESOURCE_DIRECTORY, timestamp)\n\n\ndef get_resource(context, path):\n    if path.startswith('++plone++'):\n        # ++plone++ resources can be customized, we return their override\n        # value if any\n        overrides = get_override_directory(context)\n        filepath = path[9:]\n        if overrides.isFile(filepath):\n            return overrides.readFile(filepath)\n\n    resource = context.unrestrictedTraverse(path)\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n    else:\n        if hasattr(aq_base(resource), 'GET'):\n            # for FileResource\n            return resource.GET()\n        else:\n            # any BrowserView\n            return resource()\n\n\ndef write_js(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    # default resources\n    if meta_bundle == 'default' and registry.records.get(\n        'plone.resources/jquery.js'\n    ):\n        resources.append(get_resource(context,\n            registry.records['plone.resources/jquery.js'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.requirejs'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.configjs'].value))\n\n    # bundles\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle and bundle.jscompilation:\n            resources.append(get_resource(context, bundle.jscompilation))\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".js\", fi)\n\n\ndef write_css(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle and bundle.csscompilation:\n            css = get_resource(context, bundle.csscompilation)\n            # Preserve relative urls:\n            # we prefix with '../'' any url not starting with '/'\n            # or http: or data:\n            css = re.sub(\n                r\"\"\"(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))\"\"\",\n                r'\\1../',\n                css)\n            resources.append(css)\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".css\", fi)\n\n\ndef get_override_directory(context):\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return\n    if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:\n        persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)\n    return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n\n\ndef combine_bundles(context):\n    container = get_override_directory(context)\n    if PRODUCTION_RESOURCE_DIRECTORY not in container:\n        container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)\n    production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n\n    # store timestamp\n    fi = StringIO()\n    fi.write(datetime.now().isoformat())\n    production_folder.writeFile(\"timestamp.txt\", fi)\n\n    # generate new combined bundles\n    write_js(context, production_folder, 'default')\n    write_js(context, production_folder, 'logged-in')\n    write_css(context, production_folder, 'default')\n    write_css(context, production_folder, 'logged-in')\n", "path": "Products/CMFPlone/resources/browser/combine.py"}], "after_files": [{"content": "import re\nfrom zExceptions import NotFound\nfrom Acquisition import aq_base\nfrom datetime import datetime\nfrom plone.registry.interfaces import IRegistry\nfrom plone.resource.file import FilesystemFile\nfrom plone.resource.interfaces import IResourceDirectory\nfrom Products.CMFPlone.interfaces import IBundleRegistry\nfrom Products.CMFPlone.interfaces.resources import (\n    OVERRIDE_RESOURCE_DIRECTORY_NAME,\n)\nfrom StringIO import StringIO\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nPRODUCTION_RESOURCE_DIRECTORY = \"production\"\n\n\ndef get_production_resource_directory():\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return ''\n    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n    try:\n        production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n    except NotFound:\n        return \"%s/++unique++1\" % PRODUCTION_RESOURCE_DIRECTORY\n    timestamp = production_folder.readFile('timestamp.txt')\n    return \"%s/++unique++%s\" % (\n        PRODUCTION_RESOURCE_DIRECTORY, timestamp)\n\n\ndef get_resource(context, path):\n    if path.startswith('++plone++'):\n        # ++plone++ resources can be customized, we return their override\n        # value if any\n        overrides = get_override_directory(context)\n        filepath = path[9:]\n        if overrides.isFile(filepath):\n            return overrides.readFile(filepath)\n\n    resource = context.unrestrictedTraverse(path)\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n    else:\n        if hasattr(aq_base(resource), 'GET'):\n            # for FileResource\n            return resource.GET()\n        else:\n            # any BrowserView\n            return resource()\n\n\ndef write_js(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    # default resources\n    if meta_bundle == 'default' and registry.records.get(\n        'plone.resources/jquery.js'\n    ):\n        resources.append(get_resource(context,\n            registry.records['plone.resources/jquery.js'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.requirejs'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.configjs'].value))\n\n    # bundles\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle and bundle.jscompilation:\n            resources.append(get_resource(context, bundle.jscompilation))\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".js\", fi)\n\n\ndef write_css(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle and bundle.csscompilation:\n            css = get_resource(context, bundle.csscompilation)\n            (path, sep, filename) = bundle.csscompilation.rpartition('/')\n            # Process relative urls:\n            # we prefix with current resource path any url not starting with\n            # '/' or http: or data:\n            css = re.sub(\n                r\"\"\"(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))\"\"\",\n                r'\\1%s/' % path,\n                css)\n            resources.append(css)\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".css\", fi)\n\n\ndef get_override_directory(context):\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return\n    if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:\n        persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)\n    return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n\n\ndef combine_bundles(context):\n    container = get_override_directory(context)\n    if PRODUCTION_RESOURCE_DIRECTORY not in container:\n        container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)\n    production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n\n    # store timestamp\n    fi = StringIO()\n    fi.write(datetime.now().isoformat())\n    production_folder.writeFile(\"timestamp.txt\", fi)\n\n    # generate new combined bundles\n    write_js(context, production_folder, 'default')\n    write_js(context, production_folder, 'logged-in')\n    write_css(context, production_folder, 'default')\n    write_css(context, production_folder, 'logged-in')\n", "path": "Products/CMFPlone/resources/browser/combine.py"}]}