summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-waitress/CVE-2024-49769-5.patch
blob: 14fe56e021e8de4d018512cb6400fe443868944e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
From aa161b98cc787f266d8ef358f00fc5b2b3944157 Mon Sep 17 00:00:00 2001
From: Delta Regeer <bertjw@regeer.org>
Date: Sun, 3 Mar 2024 16:35:39 -0700
Subject: [PATCH] Remove code not used by waitress from vendored asyncore

CVE: CVE-2024-49769
Upstream-Status: Backport [https://github.com/Pylons/waitress/commit/63678e652d912e67621580123c603e37c319d8c4]
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
---
 src/waitress/wasyncore.py | 45 ------------------
 tests/test_wasyncore.py   | 96 ++++++++-------------------------------
 2 files changed, 18 insertions(+), 123 deletions(-)

diff --git a/src/waitress/wasyncore.py b/src/waitress/wasyncore.py
index b5ddce2..117f78a 100644
--- a/src/waitress/wasyncore.py
+++ b/src/waitress/wasyncore.py
@@ -379,23 +379,6 @@ class dispatcher:
         self.addr = addr
         return self.socket.bind(addr)
 
-    def connect(self, address):
-        self.connected = False
-        self.connecting = True
-        err = self.socket.connect_ex(address)
-        if (
-            err in (EINPROGRESS, EALREADY, EWOULDBLOCK)
-            or err == EINVAL
-            and os.name == "nt"
-        ):  # pragma: no cover
-            self.addr = address
-            return
-        if err in (0, EISCONN):
-            self.addr = address
-            self.handle_connect_event()
-        else:
-            raise OSError(err, errorcode[err])
-
     def accept(self):
         # XXX can return either an address pair or None
         try:
@@ -557,34 +540,6 @@ class dispatcher:
         self.close()
 
 
-# ---------------------------------------------------------------------------
-# adds simple buffered output capability, useful for simple clients.
-# [for more sophisticated usage use asynchat.async_chat]
-# ---------------------------------------------------------------------------
-
-
-class dispatcher_with_send(dispatcher):
-    def __init__(self, sock=None, map=None):
-        dispatcher.__init__(self, sock, map)
-        self.out_buffer = b""
-
-    def initiate_send(self):
-        num_sent = 0
-        num_sent = dispatcher.send(self, self.out_buffer[:65536])
-        self.out_buffer = self.out_buffer[num_sent:]
-
-    handle_write = initiate_send
-
-    def writable(self):
-        return (not self.connected) or len(self.out_buffer)
-
-    def send(self, data):
-        if self.debug:  # pragma: no cover
-            self.log_info("sending %s" % repr(data))
-        self.out_buffer = self.out_buffer + data
-        self.initiate_send()
-
-
 def close_all(map=None, ignore_all=False):
     if map is None:  # pragma: no cover
         map = socket_map
diff --git a/tests/test_wasyncore.py b/tests/test_wasyncore.py
index 5f38bd9..44b8e19 100644
--- a/tests/test_wasyncore.py
+++ b/tests/test_wasyncore.py
@@ -1,6 +1,7 @@
 import _thread as thread
 import contextlib
 import errno
+from errno import EALREADY, EINPROGRESS, EINVAL, EISCONN, EWOULDBLOCK, errorcode
 import functools
 import gc
 from io import BytesIO
@@ -641,62 +642,6 @@ class DispatcherTests(unittest.TestCase):
         self.assertTrue(err != "")
 
 
-class dispatcherwithsend_noread(asyncore.dispatcher_with_send):  # pragma: no cover
-    def readable(self):
-        return False
-
-    def handle_connect(self):
-        pass
-
-
-class DispatcherWithSendTests(unittest.TestCase):
-    def setUp(self):
-        pass
-
-    def tearDown(self):
-        asyncore.close_all()
-
-    @reap_threads
-    def test_send(self):
-        evt = threading.Event()
-        sock = socket.socket()
-        sock.settimeout(3)
-        port = bind_port(sock)
-
-        cap = BytesIO()
-        args = (evt, cap, sock)
-        t = threading.Thread(target=capture_server, args=args)
-        t.start()
-        try:
-            # wait a little longer for the server to initialize (it sometimes
-            # refuses connections on slow machines without this wait)
-            time.sleep(0.2)
-
-            data = b"Suppose there isn't a 16-ton weight?"
-            d = dispatcherwithsend_noread()
-            d.create_socket()
-            d.connect((HOST, port))
-
-            # give time for socket to connect
-            time.sleep(0.1)
-
-            d.send(data)
-            d.send(data)
-            d.send(b"\n")
-
-            n = 1000
-
-            while d.out_buffer and n > 0:  # pragma: no cover
-                asyncore.poll()
-                n -= 1
-
-            evt.wait()
-
-            self.assertEqual(cap.getvalue(), data * 2)
-        finally:
-            join_thread(t, timeout=TIMEOUT)
-
-
 @unittest.skipUnless(
     hasattr(asyncore, "file_wrapper"), "asyncore.file_wrapper required"
 )
@@ -839,6 +784,23 @@ class BaseClient(BaseTestHandler):
         self.create_socket(family)
         self.connect(address)
 
+    def connect(self, address):
+        self.connected = False
+        self.connecting = True
+        err = self.socket.connect_ex(address)
+        if (
+            err in (EINPROGRESS, EALREADY, EWOULDBLOCK)
+            or err == EINVAL
+            and os.name == "nt"
+        ):  # pragma: no cover
+            self.addr = address
+            return
+        if err in (0, EISCONN):
+            self.addr = address
+            self.handle_connect_event()
+        else:
+            raise OSError(err, errorcode[err])
+
     def handle_connect(self):
         pass
 
@@ -1486,13 +1448,6 @@ class Test_dispatcher(unittest.TestCase):
         inst.set_reuse_addr()
         self.assertTrue(sock.errored)
 
-    def test_connect_raise_socket_error(self):
-        sock = dummysocket()
-        map = {}
-        sock.connect_ex = lambda *arg: 1
-        inst = self._makeOne(sock=sock, map=map)
-        self.assertRaises(socket.error, inst.connect, 0)
-
     def test_accept_raise_TypeError(self):
         sock = dummysocket()
         map = {}
@@ -1661,21 +1616,6 @@ class Test_dispatcher(unittest.TestCase):
         self.assertTrue(sock.closed)
 
 
-class Test_dispatcher_with_send(unittest.TestCase):
-    def _makeOne(self, sock=None, map=None):
-        from waitress.wasyncore import dispatcher_with_send
-
-        return dispatcher_with_send(sock=sock, map=map)
-
-    def test_writable(self):
-        sock = dummysocket()
-        map = {}
-        inst = self._makeOne(sock=sock, map=map)
-        inst.out_buffer = b"123"
-        inst.connected = True
-        self.assertTrue(inst.writable())
-
-
 class Test_close_all(unittest.TestCase):
     def _callFUT(self, map=None, ignore_all=False):
         from waitress.wasyncore import close_all