Compare commits

..

24 Commits
epel8 ... i9ce

Author SHA1 Message Date
MSVSphere Packaging Team 8d46aca41f Merge and update to 1.4.4-8
1 year ago
MSVSphere Packaging Team 2f9f9b80c3 Remove unnecessary files
1 year ago
Renata Andrade Matos Ravanelli 74f0475310 Backport fix for CVE-2022-24761
1 year ago
Carl George f30ce063b9 Switch to SPDX license identifier
2 years ago
Carl George c68e6b9057 Run test suite
2 years ago
Carl George 97a59c22b7 Convert to pyproject macros
2 years ago
Sergey Cherevko 23e0ff571e
Initial import from EPEL 9 upstream
2 years ago
Fedora Release Engineering 333344a045 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
3 years ago
Fedora Release Engineering a94b12020d - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
3 years ago
Python Maint 4893737370 Rebuilt for Python 3.10
4 years ago
Fedora Release Engineering 4e7c932d35 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
4 years ago
Troy Dawson e5ce6bf678 Remove test BuildRequires until tests are working
4 years ago
Joel Capitao 3b41398289 Update to 1.4.4
4 years ago
Fedora Release Engineering a1b1668fc8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
4 years ago
Miro Hrončok 20cd130b10 Rebuilt for Python 3.9
5 years ago
Lorenzo Gil Sanchez 5d391fb590 Update to 1.4.3 Fixes bug #1785591
5 years ago
Fedora Release Engineering 6eee6c0d5e - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
5 years ago
Lorenzo Gil Sanchez b054c6c025 Update to 1.4.2 Fixes bugs #1785591 #1789807 #1789809 #1789810 #1791415
5 years ago
Lorenzo Gil Sanchez e35378fb8a Update to 1.4.1 Fixes bug #1785591
5 years ago
Lorenzo Gil Sanchez fd1028f2e2 Update to 1.4.0 Fixes bug #1785591
5 years ago
Kevin Fenzi 0c9b05ec3b Update to 1.3.1. Fixes bug #1747075
5 years ago
Miro Hrončok a98bc75492 Subpackage python2-waitress has been removed
5 years ago
Miro Hrončok 74ca1f59f0 Rebuilt for Python 3.8
5 years ago
Fedora Release Engineering c348fb5f45 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
5 years ago

18
.gitignore vendored

@ -1,17 +1 @@
/waitress-0.8.2.tar.gz SOURCES/v1.4.4-nodocs.tar.gz
/waitress-0.8.3.tar.gz
/waitress-0.8.4.tar.gz
/waitress-0.8.5.tar.gz
/waitress-0.8.8.tar.gz
/waitress-0.8.9.tar.gz
/waitress-0.8.10.tar.gz
/waitress-0.9.0b0.tar.gz
/waitress-0.9.0b1.tar.gz
/waitress-0.9.0.tar.gz
/waitress-1.0.0.tar.gz
/waitress-1.0.1.tar.gz
/waitress-1.0.2.tar.gz
/waitress-1.1.0.tar.gz
/v1.2.1.tar.gz
/v1.2.1-nodocs.tar.gz
/v1.4.3-nodocs.tar.gz

@ -0,0 +1 @@
15091fc801ef5798d168dc34704c74f701310195 SOURCES/v1.4.4-nodocs.tar.gz

@ -1,135 +0,0 @@
From 7661d0826c9d0f197e66feed5b306b56c90255c4 Mon Sep 17 00:00:00 2001
From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:42:51 -0700
Subject: [PATCH 4/8] Error when receiving back Chunk Extension
Waitress discards chunked extensions and does no further processing on
them, however it failed to validate that the chunked encoding extension
did not contain invalid data.
We now validate that if there are any chunked extensions that they are
well-formed, if they are not and contain invalid characters, then
Waitress will now correctly return a Bad Request and stop any further
processing of the request.
(cherry picked from commit d032a669682838b26d6a1a1b513b9da83b0e0f90)
---
waitress/receiver.py | 11 ++++++++++-
waitress/tests/test_functional.py | 22 ++++++++++++++++++++++
waitress/tests/test_receiver.py | 31 +++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/waitress/receiver.py b/waitress/receiver.py
index 5d1568d..106dbc7 100644
--- a/waitress/receiver.py
+++ b/waitress/receiver.py
@@ -14,6 +14,7 @@
"""Data Chunk Receiver
"""
+from waitress.rfc7230 import CHUNK_EXT_RE, ONLY_HEXDIG_RE
from waitress.utilities import BadRequest, find_double_newline
@@ -110,6 +111,7 @@ class ChunkedReceiver(object):
s = b""
else:
self.chunk_end = b""
+
if pos == 0:
# Chop off the terminating CR LF from the chunk
s = s[2:]
@@ -140,7 +142,14 @@ class ChunkedReceiver(object):
semi = line.find(b";")
if semi >= 0:
- # discard extension info.
+ extinfo = line[semi:]
+ valid_ext_info = CHUNK_EXT_RE.match(extinfo)
+
+ if not valid_ext_info:
+ self.error = BadRequest("Invalid chunk extension")
+ self.all_chunks_received = True
+
+ break
line = line[:semi]
try:
sz = int(line.strip(), 16) # hexadecimal
diff --git a/waitress/tests/test_functional.py b/waitress/tests/test_functional.py
index 33f1317..b1aac96 100644
--- a/waitress/tests/test_functional.py
+++ b/waitress/tests/test_functional.py
@@ -343,6 +343,28 @@ class EchoTests(object):
self.send_check_error(to_send)
self.assertRaises(ConnectionClosed, read_http, fp)
+ def test_broken_chunked_encoding_invalid_extension(self):
+ control_line = b"20;invalid=\r\n" # 20 hex = 32 dec
+ s = b"This string has 32 characters.\r\n"
+ to_send = b"GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
+ to_send += control_line + s + b"\r\n"
+ self.connect()
+ self.sock.send(to_send)
+ fp = self.sock.makefile("rb", 0)
+ line, headers, response_body = read_http(fp)
+ self.assertline(line, "400", "Bad Request", "HTTP/1.1")
+ cl = int(headers["content-length"])
+ self.assertEqual(cl, len(response_body))
+ self.assertIn(b"Invalid chunk extension", response_body)
+ self.assertEqual(
+ sorted(headers.keys()),
+ ["connection", "content-length", "content-type", "date", "server"],
+ )
+ self.assertEqual(headers["content-type"], "text/plain")
+ # connection has been closed
+ self.send_check_error(to_send)
+ self.assertRaises(ConnectionClosed, read_http, fp)
+
def test_broken_chunked_encoding_missing_chunk_end(self):
control_line = "20\r\n" # 20 hex = 32 dec
s = "This string has 32 characters.\r\n"
diff --git a/waitress/tests/test_receiver.py b/waitress/tests/test_receiver.py
index b4910bb..e5d31a3 100644
--- a/waitress/tests/test_receiver.py
+++ b/waitress/tests/test_receiver.py
@@ -226,6 +226,37 @@ class TestChunkedReceiver(unittest.TestCase):
self.assertEqual(inst.error, None)
+class TestChunkedReceiverParametrized:
+ def _makeOne(self, buf):
+ from waitress.receiver import ChunkedReceiver
+
+ return ChunkedReceiver(buf)
+
+ def test_received_invalid_extensions(self):
+ from waitress.utilities import BadRequest
+
+ for invalid_extension in [b"\n", b"invalid=", b"\r", b"invalid = true"]:
+ buf = DummyBuffer()
+ inst = self._makeOne(buf)
+ data = b"4;" + invalid_extension + b"\r\ntest\r\n"
+ result = inst.received(data)
+ assert result == len(data)
+ assert inst.error.__class__ == BadRequest
+ assert inst.error.body == "Invalid chunk extension"
+
+ def test_received_valid_extensions(self):
+ # While waitress may ignore extensions in Chunked Encoding, we do want
+ # to make sure that we don't fail when we do encounter one that is
+ # valid
+ for valid_extension in [b"test", b"valid=true", b"valid=true;other=true"]:
+ buf = DummyBuffer()
+ inst = self._makeOne(buf)
+ data = b"4;" + valid_extension + b"\r\ntest\r\n"
+ result = inst.received(data)
+ assert result == len(data)
+ assert inst.error == None
+
+
class DummyBuffer(object):
def __init__(self, data=None):
if data is None:
--
2.45.2

@ -1,43 +0,0 @@
From 6e0af1e0e01f7c9a9a83431b99a82b0de5c6a5da Mon Sep 17 00:00:00 2001
From: Carl George <carlwgeorge@gmail.com>
Date: Tue, 25 Jun 2024 22:40:57 -0500
Subject: [PATCH 7/8] Backport security fix note
---
CHANGES.txt | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/CHANGES.txt b/CHANGES.txt
index 701c2b0..f9d4c42 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,26 @@
+Security Bugfix
+~~~~~~~~~~~~~~~
+
+- Waitress now validates that chunked encoding extensions are valid, and don't
+ contain invalid characters that are not allowed. They are still skipped/not
+ processed, but if they contain invalid data we no longer continue in and
+ return a 400 Bad Request. This stops potential HTTP desync/HTTP request
+ smuggling. Thanks to Zhang Zeyu for reporting this issue. See
+ https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36
+
+- Waitress now validates that the chunk length is only valid hex digits when
+ parsing chunked encoding, and values such as ``0x01`` and ``+01`` are no
+ longer supported. This stops potential HTTP desync/HTTP request smuggling.
+ Thanks to Zhang Zeyu for reporting this issue. See
+ https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36
+
+- Waitress now validates that the Content-Length sent by a remote contains only
+ digits in accordance with RFC7230 and will return a 400 Bad Request when the
+ Content-Length header contains invalid data, such as ``+10`` which would
+ previously get parsed as ``10`` and accepted. This stops potential HTTP
+ desync/HTTP request smuggling Thanks to Zhang Zeyu for reporting this issue. See
+ https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36
+
1.4.3 (2020-02-02)
------------------
--
2.45.2

@ -1,32 +0,0 @@
From 4f0407051486b5e01a148ca53f361dd802d88c59 Mon Sep 17 00:00:00 2001
From: Carl George <carlwgeorge@gmail.com>
Date: Tue, 25 Jun 2024 22:55:20 -0500
Subject: [PATCH 8/8] Skip tests that fail inconsistently during mock build
---
waitress/tests/test_functional.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/waitress/tests/test_functional.py b/waitress/tests/test_functional.py
index a7421c6..d846d06 100644
--- a/waitress/tests/test_functional.py
+++ b/waitress/tests/test_functional.py
@@ -1224,6 +1224,7 @@ class InternalServerErrorTests(object):
self.send_check_error(to_send)
self.assertRaises(ConnectionClosed, read_http, fp)
+ @unittest.skip('fails inconsistently during mock build')
def test_after_write_cb(self):
to_send = "GET /after_write_cb HTTP/1.1\r\n\r\n"
to_send = tobytes(to_send)
@@ -1237,6 +1238,7 @@ class InternalServerErrorTests(object):
self.send_check_error(to_send)
self.assertRaises(ConnectionClosed, read_http, fp)
+ @unittest.skip('fails inconsistently during mock build')
def test_in_generator(self):
to_send = "GET /in_generator HTTP/1.1\r\n\r\n"
to_send = tobytes(to_send)
--
2.45.2

@ -1,4 +1,8 @@
From b3b4d0847c0b22a6f2b12090d8b6b79c4cdea95c Mon Sep 17 00:00:00 2001 From 95f9f188665618759d8d1a27c96b3dacc3ed89be Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:22:48 -0300
Subject: [PATCH 1/6] This patch is a backport of commit: e75b0d9
From: Bert JW Regeer <bertjw@regeer.org> From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:30:30 -0700 Date: Sat, 12 Mar 2022 18:30:30 -0700
Subject: [PATCH 1/8] Add new regular expressions for Chunked Encoding Subject: [PATCH 1/8] Add new regular expressions for Chunked Encoding
@ -6,16 +10,19 @@ Subject: [PATCH 1/8] Add new regular expressions for Chunked Encoding
This also moves some regular expressions for QUOTED_PAIR/QUOTED_STRING This also moves some regular expressions for QUOTED_PAIR/QUOTED_STRING
into this module from utilities so that they may be reused. into this module from utilities so that they may be reused.
(cherry picked from commit e75b0d9afbea8a933f8f5f11d279e661cbfd676b) Backport:
* Patch refresh - no functional change.
Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
--- ---
waitress/rfc7230.py | 27 ++++++++++++++++++++++++++- src/waitress/rfc7230.py | 27 ++++++++++++++++++++++++++-
waitress/utilities.py | 28 +++------------------------- src/waitress/utilities.py | 28 +++-------------------------
2 files changed, 29 insertions(+), 26 deletions(-) 2 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/waitress/rfc7230.py b/waitress/rfc7230.py diff --git a/src/waitress/rfc7230.py b/src/waitress/rfc7230.py
index cd33c90..4c4c0a9 100644 index cd33c90..0b76a38 100644
--- a/waitress/rfc7230.py --- a/src/waitress/rfc7230.py
+++ b/waitress/rfc7230.py +++ b/src/waitress/rfc7230.py
@@ -7,6 +7,9 @@ import re @@ -7,6 +7,9 @@ import re
from .compat import tobytes from .compat import tobytes
@ -55,8 +62,8 @@ index cd33c90..4c4c0a9 100644
+) +)
+ +
+# Pre-compiled regular expressions for use elsewhere +# Pre-compiled regular expressions for use elsewhere
+ONLY_HEXDIG_RE = re.compile(tobytes("^" + HEXDIG + "+$")) +ONLY_HEXDIG_RE = re.compile(("^" + HEXDIG + "+$").encode("latin-1"))
+ONLY_DIGIT_RE = re.compile(tobytes("^" + DIGIT + "+$")) +ONLY_DIGIT_RE = re.compile(("^" + DIGIT + "+$").encode("latin-1"))
+HEADER_FIELD_RE = re.compile( +HEADER_FIELD_RE = re.compile(
tobytes( tobytes(
"^(?P<name>" + TOKEN + "):" + OWS + "(?P<value>" + FIELD_VALUE + ")" + OWS + "$" "^(?P<name>" + TOKEN + "):" + OWS + "(?P<value>" + FIELD_VALUE + ")" + OWS + "$"
@ -64,11 +71,11 @@ index cd33c90..4c4c0a9 100644
) )
+QUOTED_PAIR_RE = re.compile(QUOTED_PAIR) +QUOTED_PAIR_RE = re.compile(QUOTED_PAIR)
+QUOTED_STRING_RE = re.compile(QUOTED_STRING) +QUOTED_STRING_RE = re.compile(QUOTED_STRING)
+CHUNK_EXT_RE = re.compile(tobytes("^" + CHUNK_EXT + "$")) +CHUNK_EXT_RE = re.compile(("^" + CHUNK_EXT + "$").encode("latin-1"))
diff --git a/waitress/utilities.py b/waitress/utilities.py diff --git a/src/waitress/utilities.py b/src/waitress/utilities.py
index 556bed2..fa59657 100644 index 556bed2..fa59657 100644
--- a/waitress/utilities.py --- a/src/waitress/utilities.py
+++ b/waitress/utilities.py +++ b/src/waitress/utilities.py
@@ -22,7 +22,7 @@ import re @@ -22,7 +22,7 @@ import re
import stat import stat
import time import time
@ -122,5 +129,5 @@ index 556bed2..fa59657 100644
return value return value
elif not value.startswith('"') and not value.endswith('"'): elif not value.startswith('"') and not value.endswith('"'):
-- --
2.45.2 2.39.2 (Apple Git-143)

@ -1,7 +1,11 @@
From 4105558a82b9d4fd7d68b1887dc22f6a0b627b5f Mon Sep 17 00:00:00 2001 From c2188f39de0df7fc488703ebe0ed6e224f7be820 Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:26:52 -0300
Subject: [PATCH 2/6] This patch is a backport of commit: 1f6059f
From: Bert JW Regeer <bertjw@regeer.org> From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:32:24 -0700 Date: Sat, 12 Mar 2022 18:32:24 -0700
Subject: [PATCH 2/8] Be more strict in parsing Content-Length Subject: [PATCH] Be more strict in parsing Content-Length
Validate that we are only parsing digits and nothing else. RFC7230 is Validate that we are only parsing digits and nothing else. RFC7230 is
explicit in that the Content-Length can only exist of 1*DIGIT and may explicit in that the Content-Length can only exist of 1*DIGIT and may
@ -10,22 +14,22 @@ not include any additional sign information.
The Python int() function parses `+10` as `10` which means we were more The Python int() function parses `+10` as `10` which means we were more
lenient than the standard intended. lenient than the standard intended.
(cherry picked from commit 1f6059f4c4a3a0b256b4027eda64fb9fc311b0a6) Backport:
--- * Patch refresh - no functional change.
waitress/parser.py | 13 +++++++------
waitress/tests/test_parser.py | 24 ++++++++++++++++++++++++
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/waitress/parser.py b/waitress/parser.py Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
index fef8a3d..500730e 100644 ---
--- a/waitress/parser.py src/waitress/parser.py | 11 ++++++-----
+++ b/waitress/parser.py tests/test_parser.py | 24 ++++++++++++++++++++++++
@@ -20,8 +20,9 @@ import re 2 files changed, 30 insertions(+), 5 deletions(-)
from io import BytesIO
diff --git a/src/waitress/parser.py b/src/waitress/parser.py
index 765fe59..4c6ebeb 100644
--- a/src/waitress/parser.py
+++ b/src/waitress/parser.py
@@ -22,6 +22,7 @@ from io import BytesIO
from waitress.buffers import OverflowableBuffer from waitress.buffers import OverflowableBuffer
-from waitress.compat import tostr, unquote_bytes_to_wsgi, urlparse from waitress.compat import tostr, unquote_bytes_to_wsgi, urlparse
+from waitress.compat import tostr, tobytes, unquote_bytes_to_wsgi, urlparse
from waitress.receiver import ChunkedReceiver, FixedStreamReceiver from waitress.receiver import ChunkedReceiver, FixedStreamReceiver
+from waitress.rfc7230 import HEADER_FIELD_RE, ONLY_DIGIT_RE +from waitress.rfc7230 import HEADER_FIELD_RE, ONLY_DIGIT_RE
from waitress.utilities import ( from waitress.utilities import (
@ -39,7 +43,7 @@ index fef8a3d..500730e 100644
class ParsingError(Exception): class ParsingError(Exception):
@@ -208,7 +208,7 @@ class HTTPRequestParser(object): @@ -209,7 +209,7 @@ class HTTPRequestParser(object):
headers = self.headers headers = self.headers
for line in lines: for line in lines:
@ -48,7 +52,7 @@ index fef8a3d..500730e 100644
if not header: if not header:
raise ParsingError("Invalid header") raise ParsingError("Invalid header")
@@ -298,11 +298,12 @@ class HTTPRequestParser(object): @@ -299,11 +299,12 @@ class HTTPRequestParser(object):
self.connection_close = True self.connection_close = True
if not self.chunked: if not self.chunked:
@ -57,17 +61,17 @@ index fef8a3d..500730e 100644
- except ValueError: - except ValueError:
+ cl = headers.get("CONTENT_LENGTH", "0") + cl = headers.get("CONTENT_LENGTH", "0")
+ +
+ if not ONLY_DIGIT_RE.match(tobytes(cl)): + if not ONLY_DIGIT_RE.match(cl.encode("latin-1")):
raise ParsingError("Content-Length is invalid") raise ParsingError("Content-Length is invalid")
+ cl = int(cl) + cl = int(cl)
self.content_length = cl self.content_length = cl
if cl > 0: if cl > 0:
buf = OverflowableBuffer(self.adj.inbuf_overflow) buf = OverflowableBuffer(self.adj.inbuf_overflow)
diff --git a/waitress/tests/test_parser.py b/waitress/tests/test_parser.py diff --git a/tests/test_parser.py b/tests/test_parser.py
index 91837c7..eabf353 100644 index 91837c7..eabf353 100644
--- a/waitress/tests/test_parser.py --- a/tests/test_parser.py
+++ b/waitress/tests/test_parser.py +++ b/tests/test_parser.py
@@ -194,6 +194,30 @@ class TestHTTPRequestParser(unittest.TestCase): @@ -194,6 +194,30 @@ class TestHTTPRequestParser(unittest.TestCase):
else: # pragma: nocover else: # pragma: nocover
self.assertTrue(False) self.assertTrue(False)
@ -100,5 +104,5 @@ index 91837c7..eabf353 100644
from waitress.parser import ParsingError from waitress.parser import ParsingError
-- --
2.45.2 2.39.2 (Apple Git-143)

@ -1,8 +1,11 @@
From 42bd030d29b392baed1d427916200df75f4a4a12 Mon Sep 17 00:00:00 2001 From 82003049b2b8053d74504c4e6b3e14528a8b38ff Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:32:19 -0300
Subject: [PATCH 3/6] This patch is a backport of commit 884bed1
From: Bert JW Regeer <bertjw@regeer.org> From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:35:01 -0700 Date: Sat, 12 Mar 2022 18:35:01 -0700
Subject: [PATCH 3/8] Update tests to remove invalid chunked encoding Subject: [PATCH] Update tests to remove invalid chunked encoding chunk-size
chunk-size
RFC7230 states the following: RFC7230 states the following:
@ -17,17 +20,19 @@ Where chunk-ext is:
Only if there is a chunk-ext should there be a `;` after the 1*HEXDIG. Only if there is a chunk-ext should there be a `;` after the 1*HEXDIG.
And a chunk-ext that is empty is invalid. And a chunk-ext that is empty is invalid.
(cherry picked from commit 884bed167d09c3d5fdf0730e2ca2564eefdd4534) Backport:
* Patch refresh - no functional change.
Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
--- ---
waitress/tests/test_functional.py | 6 +++--- tests/test_functional.py | 6 +++---
waitress/tests/test_parser.py | 2 +- tests/test_parser.py | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-) 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/waitress/tests/test_functional.py b/waitress/tests/test_functional.py diff --git a/tests/test_functional.py b/tests/test_functional.py
index 8f4b262..33f1317 100644 index e894497..7a54b22 100644
--- a/waitress/tests/test_functional.py --- a/tests/test_functional.py
+++ b/waitress/tests/test_functional.py +++ b/tests/test_functional.py
@@ -301,7 +301,7 @@ class EchoTests(object): @@ -302,7 +302,7 @@ class EchoTests(object):
self.assertFalse("transfer-encoding" in headers) self.assertFalse("transfer-encoding" in headers)
def test_chunking_request_with_content(self): def test_chunking_request_with_content(self):
@ -36,7 +41,7 @@ index 8f4b262..33f1317 100644
s = b"This string has 32 characters.\r\n" s = b"This string has 32 characters.\r\n"
expected = s * 12 expected = s * 12
header = tobytes("GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n") header = tobytes("GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n")
@@ -320,7 +320,7 @@ class EchoTests(object): @@ -321,7 +321,7 @@ class EchoTests(object):
self.assertFalse("transfer-encoding" in headers) self.assertFalse("transfer-encoding" in headers)
def test_broken_chunked_encoding(self): def test_broken_chunked_encoding(self):
@ -45,7 +50,7 @@ index 8f4b262..33f1317 100644
s = "This string has 32 characters.\r\n" s = "This string has 32 characters.\r\n"
to_send = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" to_send = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
to_send += control_line + s + "\r\n" to_send += control_line + s + "\r\n"
@@ -344,7 +344,7 @@ class EchoTests(object): @@ -346,7 +346,7 @@ class EchoTests(object):
self.assertRaises(ConnectionClosed, read_http, fp) self.assertRaises(ConnectionClosed, read_http, fp)
def test_broken_chunked_encoding_missing_chunk_end(self): def test_broken_chunked_encoding_missing_chunk_end(self):
@ -54,10 +59,10 @@ index 8f4b262..33f1317 100644
s = "This string has 32 characters.\r\n" s = "This string has 32 characters.\r\n"
to_send = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" to_send = "GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
to_send += control_line + s to_send += control_line + s
diff --git a/waitress/tests/test_parser.py b/waitress/tests/test_parser.py diff --git a/tests/test_parser.py b/tests/test_parser.py
index eabf353..420f280 100644 index eabf353..420f280 100644
--- a/waitress/tests/test_parser.py --- a/tests/test_parser.py
+++ b/waitress/tests/test_parser.py +++ b/tests/test_parser.py
@@ -152,7 +152,7 @@ class TestHTTPRequestParser(unittest.TestCase): @@ -152,7 +152,7 @@ class TestHTTPRequestParser(unittest.TestCase):
b"Transfer-Encoding: chunked\r\n" b"Transfer-Encoding: chunked\r\n"
b"X-Foo: 1\r\n" b"X-Foo: 1\r\n"
@ -68,5 +73,5 @@ index eabf353..420f280 100644
b"0\r\n\r\n" b"0\r\n\r\n"
) )
-- --
2.45.2 2.39.2 (Apple Git-143)

@ -0,0 +1,152 @@
From 86a7f4d2ea10ab96a3597f64b8662fbd741e2031 Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:40:31 -0300
Subject: [PATCH 4/6] This patch is a backport of commit: d032a66
From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:42:51 -0700
Subject: [PATCH] Error when receiving back Chunk Extension
Waitress discards chunked extensions and does no further processing on
them, however it failed to validate that the chunked encoding extension
did not contain invalid data.
We now validate that if there are any chunked extensions that they are
well-formed, if they are not and contain invalid characters, then
Waitress will now correctly return a Bad Request and stop any further
processing of the request
Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
---
src/waitress/receiver.py | 11 ++++++++++-
tests/test_functional.py | 22 ++++++++++++++++++++++
tests/test_receiver.py | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/src/waitress/receiver.py b/src/waitress/receiver.py
index 5d1568d..106dbc7 100644
--- a/src/waitress/receiver.py
+++ b/src/waitress/receiver.py
@@ -14,6 +14,7 @@
"""Data Chunk Receiver
"""
+from waitress.rfc7230 import CHUNK_EXT_RE, ONLY_HEXDIG_RE
from waitress.utilities import BadRequest, find_double_newline
@@ -110,6 +111,7 @@ class ChunkedReceiver(object):
s = b""
else:
self.chunk_end = b""
+
if pos == 0:
# Chop off the terminating CR LF from the chunk
s = s[2:]
@@ -140,7 +142,14 @@ class ChunkedReceiver(object):
semi = line.find(b";")
if semi >= 0:
- # discard extension info.
+ extinfo = line[semi:]
+ valid_ext_info = CHUNK_EXT_RE.match(extinfo)
+
+ if not valid_ext_info:
+ self.error = BadRequest("Invalid chunk extension")
+ self.all_chunks_received = True
+
+ break
line = line[:semi]
try:
sz = int(line.strip(), 16) # hexadecimal
diff --git a/tests/test_functional.py b/tests/test_functional.py
index 7a54b22..853942c 100644
--- a/tests/test_functional.py
+++ b/tests/test_functional.py
@@ -345,6 +345,28 @@ class EchoTests(object):
self.send_check_error(to_send)
self.assertRaises(ConnectionClosed, read_http, fp)
+ def test_broken_chunked_encoding_invalid_extension(self):
+ control_line = b"20;invalid=\r\n" # 20 hex = 32 dec
+ s = b"This string has 32 characters.\r\n"
+ to_send = b"GET / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"
+ to_send += control_line + s + b"\r\n"
+ self.connect()
+ self.sock.send(to_send)
+ with self.sock.makefile("rb", 0) as fp:
+ line, headers, response_body = read_http(fp)
+ self.assertline(line, "400", "Bad Request", "HTTP/1.1")
+ cl = int(headers["content-length"])
+ self.assertEqual(cl, len(response_body))
+ self.assertIn(b"Invalid chunk extension", response_body)
+ self.assertEqual(
+ sorted(headers.keys()),
+ ["connection", "content-length", "content-type", "date", "server"],
+ )
+ self.assertEqual(headers["content-type"], "text/plain")
+ # connection has been closed
+ self.send_check_error(to_send)
+ self.assertRaises(ConnectionClosed, read_http, fp)
+
def test_broken_chunked_encoding_missing_chunk_end(self):
control_line = "20\r\n" # 20 hex = 32 dec
s = "This string has 32 characters.\r\n"
diff --git a/tests/test_receiver.py b/tests/test_receiver.py
index b4910bb..a6261ea 100644
--- a/tests/test_receiver.py
+++ b/tests/test_receiver.py
@@ -1,5 +1,7 @@
import unittest
+import pytest
+
class TestFixedStreamReceiver(unittest.TestCase):
def _makeOne(self, cl, buf):
@@ -226,6 +228,41 @@ class TestChunkedReceiver(unittest.TestCase):
self.assertEqual(inst.error, None)
+class TestChunkedReceiverParametrized:
+ def _makeOne(self, buf):
+ from waitress.receiver import ChunkedReceiver
+
+ return ChunkedReceiver(buf)
+
+ @pytest.mark.parametrize(
+ "invalid_extension", [b"\n", b"invalid=", b"\r", b"invalid = true"]
+ )
+ def test_received_invalid_extensions(self, invalid_extension):
+ from waitress.utilities import BadRequest
+
+ buf = DummyBuffer()
+ inst = self._makeOne(buf)
+ data = b"4;" + invalid_extension + b"\r\ntest\r\n"
+ result = inst.received(data)
+ assert result == len(data)
+ assert inst.error.__class__ == BadRequest
+ assert inst.error.body == "Invalid chunk extension"
+
+ @pytest.mark.parametrize(
+ "valid_extension", [b"test", b"valid=true", b"valid=true;other=true"]
+ )
+ def test_received_valid_extensions(self, valid_extension):
+ # While waitress may ignore extensions in Chunked Encoding, we do want
+ # to make sure that we don't fail when we do encounter one that is
+ # valid
+ buf = DummyBuffer()
+ inst = self._makeOne(buf)
+ data = b"4;" + valid_extension + b"\r\ntest\r\n"
+ result = inst.received(data)
+ assert result == len(data)
+ assert inst.error == None
+
+
class DummyBuffer(object):
def __init__(self, data=None):
if data is None:
--
2.39.2 (Apple Git-143)

@ -1,7 +1,11 @@
From 4f0c74f6aab47c599d33d36cd783b5fa330384d9 Mon Sep 17 00:00:00 2001 From b0ae7e3e156ac6f4a30ac4a54af0bffb707b008d Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:41:06 -0300
Subject: [PATCH 5/6] This patch is a backport of commit d9bdfa0
From: Bert JW Regeer <bertjw@regeer.org> From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 18:48:26 -0700 Date: Sat, 12 Mar 2022 18:48:26 -0700
Subject: [PATCH 5/8] Validate chunk size in Chunked Encoding are HEXDIG Subject: [PATCH] Validate chunk size in Chunked Encoding are HEXDIG
RFC7230 states that a chunk-size should be 1*HEXDIG, this is now RFC7230 states that a chunk-size should be 1*HEXDIG, this is now
validated before passing the resulting string to int() which would also validated before passing the resulting string to int() which would also
@ -13,17 +17,17 @@ leading to request smuggling.
With the increased validation if the size is not just hex digits, With the increased validation if the size is not just hex digits,
Waitress now returns a Bad Request and stops processing the request. Waitress now returns a Bad Request and stops processing the request.
(cherry picked from commit d9bdfa0cf210f6daf017d7c5a3cc149bdec8a9a7) Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
--- ---
waitress/receiver.py | 19 ++++++++++++++----- src/waitress/receiver.py | 19 ++++++++++++++-----
waitress/tests/test_functional.py | 22 ++++++++++++++++++++++ tests/test_functional.py | 22 ++++++++++++++++++++++
waitress/tests/test_receiver.py | 12 ++++++++++++ tests/test_receiver.py | 12 ++++++++++++
3 files changed, 48 insertions(+), 5 deletions(-) 3 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/waitress/receiver.py b/waitress/receiver.py diff --git a/src/waitress/receiver.py b/src/waitress/receiver.py
index 106dbc7..9e4bffe 100644 index 106dbc7..9e4bffe 100644
--- a/waitress/receiver.py --- a/src/waitress/receiver.py
+++ b/waitress/receiver.py +++ b/src/waitress/receiver.py
@@ -150,12 +150,21 @@ class ChunkedReceiver(object): @@ -150,12 +150,21 @@ class ChunkedReceiver(object):
self.all_chunks_received = True self.all_chunks_received = True
@ -51,11 +55,11 @@ index 106dbc7..9e4bffe 100644
if sz > 0: if sz > 0:
# Start a new chunk. # Start a new chunk.
diff --git a/waitress/tests/test_functional.py b/waitress/tests/test_functional.py diff --git a/tests/test_functional.py b/tests/test_functional.py
index b1aac96..a7421c6 100644 index 853942c..448e0c0 100644
--- a/waitress/tests/test_functional.py --- a/tests/test_functional.py
+++ b/waitress/tests/test_functional.py +++ b/tests/test_functional.py
@@ -343,6 +343,28 @@ class EchoTests(object): @@ -345,6 +345,28 @@ class EchoTests(object):
self.send_check_error(to_send) self.send_check_error(to_send)
self.assertRaises(ConnectionClosed, read_http, fp) self.assertRaises(ConnectionClosed, read_http, fp)
@ -66,47 +70,47 @@ index b1aac96..a7421c6 100644
+ to_send += control_line + s + b"\r\n" + to_send += control_line + s + b"\r\n"
+ self.connect() + self.connect()
+ self.sock.send(to_send) + self.sock.send(to_send)
+ fp = self.sock.makefile("rb", 0) + with self.sock.makefile("rb", 0) as fp:
+ line, headers, response_body = read_http(fp) + line, headers, response_body = read_http(fp)
+ self.assertline(line, "400", "Bad Request", "HTTP/1.1") + self.assertline(line, "400", "Bad Request", "HTTP/1.1")
+ cl = int(headers["content-length"]) + cl = int(headers["content-length"])
+ self.assertEqual(cl, len(response_body)) + self.assertEqual(cl, len(response_body))
+ self.assertIn(b"Invalid chunk size", response_body) + self.assertIn(b"Invalid chunk size", response_body)
+ self.assertEqual( + self.assertEqual(
+ sorted(headers.keys()), + sorted(headers.keys()),
+ ["connection", "content-length", "content-type", "date", "server"], + ["connection", "content-length", "content-type", "date", "server"],
+ ) + )
+ self.assertEqual(headers["content-type"], "text/plain") + self.assertEqual(headers["content-type"], "text/plain")
+ # connection has been closed + # connection has been closed
+ self.send_check_error(to_send) + self.send_check_error(to_send)
+ self.assertRaises(ConnectionClosed, read_http, fp) + self.assertRaises(ConnectionClosed, read_http, fp)
+ +
def test_broken_chunked_encoding_invalid_extension(self): def test_broken_chunked_encoding_invalid_extension(self):
control_line = b"20;invalid=\r\n" # 20 hex = 32 dec control_line = b"20;invalid=\r\n" # 20 hex = 32 dec
s = b"This string has 32 characters.\r\n" s = b"This string has 32 characters.\r\n"
diff --git a/waitress/tests/test_receiver.py b/waitress/tests/test_receiver.py diff --git a/tests/test_receiver.py b/tests/test_receiver.py
index e5d31a3..b539264 100644 index a6261ea..17328d4 100644
--- a/waitress/tests/test_receiver.py --- a/tests/test_receiver.py
+++ b/waitress/tests/test_receiver.py +++ b/tests/test_receiver.py
@@ -256,6 +256,18 @@ class TestChunkedReceiverParametrized: @@ -262,6 +262,18 @@ class TestChunkedReceiverParametrized:
assert result == len(data) assert result == len(data)
assert inst.error == None assert inst.error == None
+ @pytest.mark.parametrize("invalid_size", [b"0x04", b"+0x04", b"x04", b"+04"])
+ def test_received_invalid_size(self, invalid_size): + def test_received_invalid_size(self, invalid_size):
+ from waitress.utilities import BadRequest + from waitress.utilities import BadRequest
+ +
+ for invalid_size in [b"0x04", b"+0x04", b"x04", b"+04"]: + buf = DummyBuffer()
+ buf = DummyBuffer() + inst = self._makeOne(buf)
+ inst = self._makeOne(buf) + data = invalid_size + b"\r\ntest\r\n"
+ data = invalid_size + b"\r\ntest\r\n" + result = inst.received(data)
+ result = inst.received(data) + assert result == len(data)
+ assert result == len(data) + assert inst.error.__class__ == BadRequest
+ assert inst.error.__class__ == BadRequest + assert inst.error.body == "Invalid chunk size"
+ assert inst.error.body == "Invalid chunk size"
+ +
class DummyBuffer(object): class DummyBuffer(object):
def __init__(self, data=None): def __init__(self, data=None):
-- --
2.45.2 2.39.2 (Apple Git-143)

@ -1,7 +1,12 @@
From 92c5f8b8dbfc73780f8404b225b1282d58c5cd96 Mon Sep 17 00:00:00 2001 From ef0b3d7cb9f532c062052082f71174ef94d4a3e3 Mon Sep 17 00:00:00 2001
From: Renata Ravanelli <renata.ravanelli@gmail.com>
Date: Fri, 15 Sep 2023 12:41:52 -0300
Subject: [PATCH 6/6] This patch is a backport of commit bd22869
From bd22869 Mon Sep 17 00:00:00 2001
From: Bert JW Regeer <bertjw@regeer.org> From: Bert JW Regeer <bertjw@regeer.org>
Date: Sat, 12 Mar 2022 19:16:23 -0700 Date: Sat, 12 Mar 2022 19:16:23 -0700
Subject: [PATCH 6/8] Remove extraneous calls to .strip() in Chunked Encoding Subject: [PATCH] Remove extraneous calls to .strip() in Chunked Encoding
To be valid chunked encoding we should not be removing any whitespace as To be valid chunked encoding we should not be removing any whitespace as
the standard does not allow for optional whitespace. the standard does not allow for optional whitespace.
@ -9,16 +14,19 @@ the standard does not allow for optional whitespace.
If whitespace is encountered in the wrong place, it should lead to a 400 If whitespace is encountered in the wrong place, it should lead to a 400
Bad Request instead. Bad Request instead.
(cherry picked from commit bd22869c143a3f1284f271399524676efbafa655) Backport:
* Patch refresh - no functional change.
Signed-off-by: Renata Ravanelli <renata.ravanelli@gmail.com>
--- ---
waitress/receiver.py | 6 +----- src/waitress/receiver.py | 6 +-----
waitress/tests/test_receiver.py | 2 +- tests/test_receiver.py | 4 +++-
2 files changed, 2 insertions(+), 6 deletions(-) 2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/waitress/receiver.py b/waitress/receiver.py diff --git a/src/waitress/receiver.py b/src/waitress/receiver.py
index 9e4bffe..806ff87 100644 index 9e4bffe..806ff87 100644
--- a/waitress/receiver.py --- a/src/waitress/receiver.py
+++ b/waitress/receiver.py +++ b/src/waitress/receiver.py
@@ -135,7 +135,6 @@ class ChunkedReceiver(object): @@ -135,7 +135,6 @@ class ChunkedReceiver(object):
line = s[:pos] line = s[:pos]
s = s[pos + 2 :] s = s[pos + 2 :]
@ -46,19 +54,21 @@ index 9e4bffe..806ff87 100644
if sz > 0: if sz > 0:
# Start a new chunk. # Start a new chunk.
diff --git a/waitress/tests/test_receiver.py b/waitress/tests/test_receiver.py diff --git a/tests/test_receiver.py b/tests/test_receiver.py
index b539264..fd192c1 100644 index 17328d4..014f785 100644
--- a/waitress/tests/test_receiver.py --- a/tests/test_receiver.py
+++ b/waitress/tests/test_receiver.py +++ b/tests/test_receiver.py
@@ -259,7 +259,7 @@ class TestChunkedReceiverParametrized: @@ -262,7 +262,9 @@ class TestChunkedReceiverParametrized:
assert result == len(data)
assert inst.error == None
- @pytest.mark.parametrize("invalid_size", [b"0x04", b"+0x04", b"x04", b"+04"])
+ @pytest.mark.parametrize(
+ "invalid_size", [b"0x04", b"+0x04", b"x04", b"+04", b" 04", b" 0x04"]
+ )
def test_received_invalid_size(self, invalid_size): def test_received_invalid_size(self, invalid_size):
from waitress.utilities import BadRequest from waitress.utilities import BadRequest
- for invalid_size in [b"0x04", b"+0x04", b"x04", b"+04"]:
+ for invalid_size in [b"0x04", b"+0x04", b"x04", b"+04", b" 04", b" 0x04"]:
buf = DummyBuffer()
inst = self._makeOne(buf)
data = invalid_size + b"\r\ntest\r\n"
-- --
2.45.2 2.39.2 (Apple Git-143)

@ -1,14 +1,10 @@
%global srcname waitress Name: python-waitress
Version: 1.4.4
%global _docdir_fmt %{name} Release: 8%{?dist}
Name: python-%{srcname}
Version: 1.4.3
Release: 2%{?dist}
Summary: Waitress WSGI server Summary: Waitress WSGI server
License: ZPLv2.1 License: ZPL-2.1
URL: https://github.com/Pylons/%{srcname} URL: https://github.com/Pylons/waitress
Source0: v%{version}-nodocs.tar.gz Source0: v%{version}-nodocs.tar.gz
# Upstream ships non free docs files. # Upstream ships non free docs files.
# We do not even want them in our src.rpms # We do not even want them in our src.rpms
@ -20,21 +16,14 @@ Source0: v%{version}-nodocs.tar.gz
# #
Source1: generate-tarball.sh Source1: generate-tarball.sh
# https://github.com/Pylons/waitress/commit/e75b0d9afbea8a933f8f5f11d279e661cbfd676b # These patches are backports based on RHEL patch #923591398b8553c7ba295dfede592671b653f946
Patch1: 0001-Add-new-regular-expressions-for-Chunked-Encoding.patch
# https://github.com/Pylons/waitress/commit/1f6059f4c4a3a0b256b4027eda64fb9fc311b0a6 Patch1: 0001-This-patch-is-a-backport-of-commit-e75b0d9.patch
Patch2: 0002-Be-more-strict-in-parsing-Content-Length.patch Patch2: 0002-This-patch-is-a-backport-of-commit-1f6059f.patch
# https://github.com/Pylons/waitress/commit/884bed167d09c3d5fdf0730e2ca2564eefdd4534 Patch3: 0003-This-patch-is-a-backport-of-commit-884bed1.patch
Patch3: 0003-Update-tests-to-remove-invalid-chunked-encoding-chunk-size.patch Patch4: 0004-This-patch-is-a-backport-of-commit-d032a66.patch
# https://github.com/Pylons/waitress/commit/d032a669682838b26d6a1a1b513b9da83b0e0f90 Patch5: 0005-This-patch-is-a-backport-of-commit-d9bdfa0.patch
Patch4: 0004-Error-when-receiving-back-Chunk-Extension.patch Patch6: 0006-This-patch-is-a-backport-of-commit-bd22869.patch
# https://github.com/Pylons/waitress/commit/d9bdfa0cf210f6daf017d7c5a3cc149bdec8a9a7
Patch5: 0005-Validate-chunk-size-in-Chunked-Encoding-are-HEXDIG.patch
# https://github.com/Pylons/waitress/commit/bd22869c143a3f1284f271399524676efbafa655
Patch6: 0006-Remove-extraneous-calls-to-.strip-in-Chunked-Encoding.patch
# downstream only patches
Patch7: 0007-Backport-security-fix-note.patch
Patch8: 0008-Skip-tests-that-fail-inconsistently-during-mock-build.patch
BuildArch: noarch BuildArch: noarch
@ -42,74 +31,106 @@ BuildArch: noarch
Waitress is meant to be a production-quality pure-Python WSGI server with very Waitress is meant to be a production-quality pure-Python WSGI server with very
acceptable performance. It has no dependencies except ones which live in the acceptable performance. It has no dependencies except ones which live in the
Python standard library. It runs on CPython on Unix and Windows under Python Python standard library. It runs on CPython on Unix and Windows under Python
2.7+ and Python 3.4+. It is also known to run on PyPy 1.6.0+ on UNIX. It 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0+ on UNIX. It
supports HTTP/1.0 and HTTP/1.1.} supports HTTP/1.0 and HTTP/1.1.}
%description %{_description} %description %{_description}
%package -n python2-%{srcname} %package -n python3-waitress
Summary: %{summary}
BuildRequires: python2-devel
BuildRequires: python2-setuptools
BuildRequires: python2-nose
%description -n python2-%{srcname} %{_description}
Python 2 version.
%package -n python3-%{srcname}
Summary: %{summary} Summary: %{summary}
BuildRequires: python3-devel BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-nose
%description -n python3-%{srcname} %{_description}
Python 3 version. %description -n python3-waitress %{_description}
%prep %prep
%autosetup -n %{srcname}-%{version}-nodocs -p 1 %autosetup -n waitress-%{version}-nodocs -p 1
sed -e '/pytest-cover/d' \
-e '/coverage/d' \
-e '/addopts/d' \
-i setup.cfg
%generate_buildrequires
%pyproject_buildrequires -x testing
%build %build
%py2_build %pyproject_wheel
%py3_build
%install %install
%py2_install %pyproject_install
%py3_install %pyproject_save_files waitress
%check %check
PYTHONPATH=%{buildroot}%{python2_sitelib} nosetests-%{python2_version} %{srcname} %pytest
PYTHONPATH=%{buildroot}%{python3_sitelib} nosetests-%{python3_version} %{srcname}
%files -n python2-%{srcname}
%license COPYRIGHT.txt LICENSE.txt
%doc README.rst CHANGES.txt
%{python2_sitelib}/%{srcname}/
%{python2_sitelib}/%{srcname}-*.egg-info/
%files -n python3-%{srcname} %files -n python3-waitress -f %{pyproject_files}
%license COPYRIGHT.txt LICENSE.txt %license COPYRIGHT.txt LICENSE.txt
%doc README.rst CHANGES.txt %doc README.rst CHANGES.txt
%{_bindir}/waitress-serve %{_bindir}/waitress-serve
%{python3_sitelib}/%{srcname}/
%{python3_sitelib}/%{srcname}-*.egg-info/
%changelog %changelog
* Wed Jun 26 2024 Carl George <carlwgeorge@fedoraproject.org> - 1.4.3-2 * Fri Jul 21 2023 Renata Ravanelli <rravanel@redhat.com> - 1.4.4-8
- Backport upstream fix for CVE-2022-24761 rhbz#2065791 - Backport changes to fix CVE-2022-24761
* Wed May 10 2023 Carl George <carl@george.computer> - 1.4.3-1 * Wed May 10 2023 Carl George <carl@george.computer> - 1.4.4-7
- Update to version 1.4.3 - Convert to pyproject macros
- Resolves: rhbz#1791421 CVE-2019-16785
- Resolves: rhbz#1791417 CVE-2019-16786
- Resolves: rhbz#1789810 CVE-2019-16789
- Resolves: CVE-2019-16792
- Resolves: CVE-2020-5236
- Run test suite - Run test suite
- Switch to SPDX license identifier
* Fri Apr 28 2023 Sergey Cherevko <s.cherevko@msvsphere.ru> - 1.4.4-6
- Rebuilt for MSVSphere 9.1
* Fri Jan 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.4-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.4-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Thu Jun 03 2021 Python Maint <python-maint@redhat.com> - 1.4.4-4
- Rebuilt for Python 3.10
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.4-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Jan 15 2021 Troy Dawson <tdawson@redhat.com> - 1.4.4-2
- Remove test BuildRequires until tests are working
* Thu Sep 10 2020 Joel Capitao <jcapitao@redhat.com> - 1.4.4-1
- Update to 1.4.4
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Sat May 23 2020 Miro Hrončok <mhroncok@redhat.com> - 1.4.3-2
- Rebuilt for Python 3.9
* Fri Feb 07 2020 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> - 1.4.3-1
- Update to 1.4.3 Fixes bug #1785591
* Thu Jan 30 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Jan 20 2020 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> - 1.4.2-1
- Update to 1.4.2 Fixes bugs #1785591 #1789807 #1789809 #1789810 #1791415
#1791416 #1791417 #1791420 #1791421 #1791422 #1791423
* Thu Jan 16 2020 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> - 1.4.1-1
- Update to 1.4.1 Fixes bug #1785591
* Wed Dec 25 2019 Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com> - 1.4.0-1
- Update to 1.4.0 Fixes bug #1785591
* Sun Oct 06 2019 Kevin Fenzi <kevin@scrye.com> - 1.3.1-1
- Update to 1.3.1. Fixes bug #1747075
* Mon Sep 09 2019 Miro Hrončok <mhroncok@redhat.com> - 1.2.1-5
- Subpackage python2-waitress has been removed
See https://fedoraproject.org/wiki/Changes/Mass_Python_2_Package_Removal
* Sat Aug 17 2019 Miro Hrončok <mhroncok@redhat.com> - 1.2.1-4
- Rebuilt for Python 3.8
* Wed Jul 24 2019 Stephen Smoogen <smooge@fedoraproject.org> - 1.2.1-2.1 * Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.1-3
- Change out python3-coverage with standard lookup call. - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sat Jun 29 2019 Kevin Fenzi <kevin@scrye.com> - 1.2.1-2 * Sat Jun 29 2019 Kevin Fenzi <kevin@scrye.com> - 1.2.1-2
- Remove non free docs from src.rpm and provide script to do so before upload. - Remove non free docs from src.rpm and provide script to do so before upload.

@ -1 +0,0 @@
SHA512 (v1.4.3-nodocs.tar.gz) = c3749376e97d864874b1976b7f9f2688d3b55c56e33a01d968fc59a068a27ea14dd389d8ca4feb211afbfd0bb6848f6b8d483142e0b7a1b403f924fb7cb87f3c
Loading…
Cancel
Save