nebius/SWE-bench-extra huggingface dataset:
Repository: cherrypy/cherrypy

Issue:
Encode URLs in redirect responses
* **I'm submitting a ...**
[x] bug report
[ ] feature request
[ ] question about the decisions made in the repository

* **What is the current behavior?**
The standard response page for 30x errors contains the target URL as `href` as well as clear text.

* **What is the expected behavior?**
Even though browsers *mostly* will not display the result, but redirect instead, you never know:
Any input from unknown sources should be html-escaped.

* **Please tell us about your environment:**
CherryPy 3.8 until 10.1


Comments:

Patch:
diff --git a/cherrypy/_cperror.py b/cherrypy/_cperror.py
index 6c952e91..b597c645 100644
--- a/cherrypy/_cperror.py
+++ b/cherrypy/_cperror.py
@@ -271,7 +271,7 @@ class HTTPRedirect(CherryPyException):
                 307: 'This resource has moved temporarily to ',
             }[status]
             msg += '<a href=%s>%s</a>.'
-            msgs = [msg % (saxutils.quoteattr(u), u) for u in self.urls]
+            msgs = [msg % (saxutils.quoteattr(u), escape_html(u)) for u in self.urls]
             response.body = ntob('<br />\n'.join(msgs), 'utf-8')
             # Previous code may have set C-L, so we have to reset it
             # (allow finalize to set it).


Test patch:
diff --git a/cherrypy/test/test_core.py b/cherrypy/test/test_core.py
index 2e590a9d..f16efd58 100644
--- a/cherrypy/test/test_core.py
+++ b/cherrypy/test/test_core.py
@@ -150,6 +150,9 @@ class CoreRequestHandlingTest(helper.CPWebCase):
             def url_with_quote(self):
                 raise cherrypy.HTTPRedirect("/some\"url/that'we/want")
 
+            def url_with_xss(self):
+                raise cherrypy.HTTPRedirect("/some<script>alert(1);</script>url/that'we/want")
+
             def url_with_unicode(self):
                 raise cherrypy.HTTPRedirect(ntou('тест', 'utf-8'))
 
@@ -435,6 +438,13 @@ class CoreRequestHandlingTest(helper.CPWebCase):
         self.assertStatus(303)
         assertValidXHTML()
 
+    def test_redirect_with_xss(self):
+        """A redirect to a URL with HTML injected should result in page contents escaped."""
+        self.getPage('/redirect/url_with_xss')
+        self.assertStatus(303)
+        assert b'<script>' not in self.body
+        assert b'&lt;script&gt;' in self.body
+
     def test_redirect_with_unicode(self):
         """
         A redirect to a URL with Unicode should return a Location
Repository: cherrypy/cherrypy

Issue:
Proxy tools causes double port, creating broken links
Consider this script:

```
__requires__ = ['cherrypy']

import os

import cherrypy


class Server:
	@cherrypy.expose
	def index(self):
		return cherrypy.url('/foo/')

	@classmethod
	def run(cls):
		config = {
			'global': {
				'server.socket_port': int(os.environ.get('PORT', 8080)),
				'tools.proxy.on': True,
			},
		}
		cherrypy.quickstart(cls(), config=config)


__name__ == '__main__' and Server.run()
```

Run it and request `/` and you'll get:

```
$ curl http://localhost:8080/
http://localhost:8080:8080/foo/
```

Comments:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index ea4f70ca..215f33ed 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,3 +1,9 @@
+v11.0.1
+-------
+
+* #1627: Fixed issue in proxy tool where more than one port would
+  appear in the ``request.base`` and thus in ``cherrypy.url``.
+
 v11.0.0
 -------
 
diff --git a/cherrypy/lib/cptools.py b/cherrypy/lib/cptools.py
index 2ad5a44d..4e85c9c2 100644
--- a/cherrypy/lib/cptools.py
+++ b/cherrypy/lib/cptools.py
@@ -5,6 +5,7 @@ import re
 from hashlib import md5
 
 import six
+from six.moves import urllib
 
 import cherrypy
 from cherrypy._cpcompat import text_or_bytes
@@ -195,10 +196,8 @@ def proxy(base=None, local='X-Forwarded-Host', remote='X-Forwarded-For',
         if lbase is not None:
             base = lbase.split(',')[0]
     if not base:
-        base = request.headers.get('Host', '127.0.0.1')
-        port = request.local.port
-        if port != 80:
-            base += ':%s' % port
+        default = urllib.parse.urlparse(request.base).netloc
+        base = request.headers.get('Host', default)
 
     if base.find('://') == -1:
         # add http:// or https:// if needed


Test patch:
diff --git a/cherrypy/test/test_proxy.py b/cherrypy/test/test_proxy.py
index 0cb209fb..4d34440a 100644
--- a/cherrypy/test/test_proxy.py
+++ b/cherrypy/test/test_proxy.py
@@ -58,6 +58,13 @@ class ProxyTest(helper.CPWebCase):
                 return ("Browse to <a href='%s'>this page</a>."
                         % cherrypy.url('/this/new/page'))
 
+            @cherrypy.expose
+            @cherrypy.config(**{
+                'tools.proxy.base': None,
+            })
+            def base_no_base(self):
+                return cherrypy.request.base
+
         for sn in script_names:
             cherrypy.tree.mount(Root(sn), sn)
 
@@ -136,3 +143,12 @@ class ProxyTest(helper.CPWebCase):
         self.getPage('/xhost/', headers=[('X-Host', 'www.example.test')])
         self.assertHeader('Location', '%s://www.example.test/xhost'
                           % self.scheme)
+
+    def test_no_base_port_in_host(self):
+        """
+        If no base is indicated, and the host header is used to resolve
+        the base, it should rely on the host header for the port also.
+        """
+        headers = {'Host': 'localhost:8080'}.items()
+        self.getPage('/base_no_base', headers=headers)
+        self.assertBody('http://localhost:8080')
Repository: cherrypy/cherrypy

Issue:
`setuptools_scm_git_archive` is obsolete
The `setuptools_scm_git_archive` package is obsolete.  Please switch to `setuptools_scm >= 7.0.0`.

Comments:

Patch:
diff --git a/.git_archival.txt b/.git_archival.txt
new file mode 100644
index 00000000..3994ec0a
--- /dev/null
+++ b/.git_archival.txt
@@ -0,0 +1,4 @@
+node: $Format:%H$
+node-date: $Format:%cI$
+describe-name: $Format:%(describe:tags=true)$
+ref-names: $Format:%D$
diff --git a/.gitattributes b/.gitattributes
index 00e5815f..84cc7a59 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,1 +1,7 @@
+# Needed for setuptools-scm-git-archive
+.git_archival.txt  export-subst
+
+# Blame ignore list entries are expected to always be appended, never edited
+.git-blame-ignore-revs  merge=union
+
 /CHANGES.rst merge=union
diff --git a/docs/conf.py b/docs/conf.py
index 4a0ceb54..ebd25867 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -203,7 +203,7 @@ link_files = {
         ),
         replace=[
             dict(
-                pattern=r'^(?m)((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n',
+                pattern=r'(?m)^((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n',
                 with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n',
             ),
         ],
diff --git a/pyproject.toml b/pyproject.toml
index a29ffa3b..2c3a7cff 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,8 +4,7 @@ requires = [
     "setuptools >= 45",
 
     # Plugins
-    "setuptools_scm[toml] >= 3.5",
-    "setuptools_scm_git_archive >= 1.1",
+    "setuptools_scm[toml] >= 7.0.0",
 ]
 build-backend = "setuptools.build_meta"
 


Test patch:
diff --git a/cherrypy/test/test_session.py b/cherrypy/test/test_session.py
index 80567504..f566c37f 100755
--- a/cherrypy/test/test_session.py
+++ b/cherrypy/test/test_session.py
@@ -146,9 +146,14 @@ class SessionTest(helper.CPWebCase):
     def teardown_class(cls):
         """Clean up sessions."""
         super(cls, cls).teardown_class()
+        try:
+            files_to_clean = localDir.iterdir()  # Python 3.8+
+        except AttributeError:
+            files_to_clean = localDir.listdir()  # Python 3.6-3.7
+
         consume(
             file.remove_p()
-            for file in localDir.iterdir()
+            for file in files_to_clean
             if file.basename().startswith(
                 sessions.FileSession.SESSION_PREFIX
             )