hiredis 3.4.0.dev0__tar.gz → 3.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hiredis-3.4.0.dev0/hiredis.egg-info → hiredis-3.4.2}/PKG-INFO +1 -1
- hiredis-3.4.2/hiredis/version.py +1 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2/hiredis.egg-info}/PKG-INFO +1 -1
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis.egg-info/SOURCES.txt +1 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/reader.c +19 -5
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/tests/test_reader.py +30 -0
- hiredis-3.4.2/vendor/hiredis/ffc.h +3451 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/hiredis.c +4 -1
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/hiredis.h +4 -3
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/net.c +23 -4
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/read.c +82 -2
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/sds.h +9 -2
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/sockcompat.h +1 -1
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/test.c +76 -3
- hiredis-3.4.0.dev0/hiredis/version.py +0 -1
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/LICENSE +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/MANIFEST.in +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/README.md +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis/__init__.py +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis/hiredis.pyi +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis/py.typed +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis.egg-info/dependency_links.txt +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/hiredis.egg-info/top_level.txt +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/setup.cfg +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/setup.py +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/hiredis.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/hiredis.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/pack.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/pack.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/src/reader.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/tests/test_gc.py +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/tests/test_pack.py +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/COPYING +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/alloc.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/alloc.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/async.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/async.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/async_private.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/dict.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/dict.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/fmacros.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/hiredis_ssl.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/net.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/read.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/sds.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/sdsalloc.h +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/sockcompat.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/ssl.c +0 -0
- {hiredis-3.4.0.dev0 → hiredis-3.4.2}/vendor/hiredis/win32.h +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.4.2"
|
|
@@ -83,6 +83,10 @@ PyTypeObject PushNotificationType = {
|
|
|
83
83
|
|
|
84
84
|
static void *tryParentize(const redisReadTask *task, PyObject *obj) {
|
|
85
85
|
PyObject *parent;
|
|
86
|
+
if (obj == NULL) {
|
|
87
|
+
/* The caller failed to allocate; propagate so hiredis reports OOM. */
|
|
88
|
+
return NULL;
|
|
89
|
+
}
|
|
86
90
|
if (task && task->parent) {
|
|
87
91
|
parent = (PyObject*)task->parent->obj;
|
|
88
92
|
switch (task->parent->type) {
|
|
@@ -242,12 +246,22 @@ static PyObject* PushNotificationType_New(Py_ssize_t size) {
|
|
|
242
246
|
return NULL;
|
|
243
247
|
}
|
|
244
248
|
|
|
245
|
-
|
|
249
|
+
/* Pre-sizes the notification, whose elements are filled in as they parse.
|
|
250
|
+
* PyList_SetSlice does not steal a reference to the list it is handed, so
|
|
251
|
+
* it has to be released here. */
|
|
252
|
+
PyObject* items = PyList_New(size);
|
|
253
|
+
if (items == NULL) {
|
|
254
|
+
Py_DECREF(obj);
|
|
255
|
+
return NULL;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
int res = PyList_SetSlice(obj, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, items);
|
|
259
|
+
Py_DECREF(items);
|
|
246
260
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
261
|
+
if (res == -1) {
|
|
262
|
+
Py_DECREF(obj);
|
|
263
|
+
return NULL;
|
|
264
|
+
}
|
|
251
265
|
|
|
252
266
|
return obj;
|
|
253
267
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import gc
|
|
2
|
+
import platform
|
|
3
|
+
|
|
1
4
|
import hiredis
|
|
2
5
|
import pytest
|
|
3
6
|
|
|
@@ -191,6 +194,33 @@ def test_vector(reader):
|
|
|
191
194
|
assert isinstance(result, hiredis.PushNotification)
|
|
192
195
|
assert [b"pubsub", b"message", b"channel", b"message"] == result
|
|
193
196
|
|
|
197
|
+
@pytest.mark.skipif(platform.python_implementation() != "CPython",
|
|
198
|
+
reason="requires CPython reference counting")
|
|
199
|
+
def test_push_notification_releases_backing_list(reader):
|
|
200
|
+
# The list a notification is sized from is only borrowed by PyList_SetSlice,
|
|
201
|
+
# so not releasing it strands one list per notification received.
|
|
202
|
+
payload = b">4\r\n+pubsub\r\n+message\r\n+channel\r\n+message\r\n"
|
|
203
|
+
iterations = 512
|
|
204
|
+
|
|
205
|
+
def live_lists():
|
|
206
|
+
return sum(1 for obj in gc.get_objects() if type(obj) is list)
|
|
207
|
+
|
|
208
|
+
for _ in range(8):
|
|
209
|
+
reader.feed(payload)
|
|
210
|
+
reader.gets()
|
|
211
|
+
gc.collect()
|
|
212
|
+
before = live_lists()
|
|
213
|
+
|
|
214
|
+
for _ in range(iterations):
|
|
215
|
+
reader.feed(payload)
|
|
216
|
+
reader.gets()
|
|
217
|
+
gc.collect()
|
|
218
|
+
|
|
219
|
+
# Leaking strands exactly one list per iteration, so the bug reads as a delta
|
|
220
|
+
# of 512 where a fixed build measures 0. The bound is left far above 0 only so
|
|
221
|
+
# that allocations elsewhere in the run cannot make this flaky.
|
|
222
|
+
assert live_lists() - before < iterations // 8
|
|
223
|
+
|
|
194
224
|
def test_verbatim_string(reader):
|
|
195
225
|
value = b"text"
|
|
196
226
|
reader.feed(b"=8\r\ntxt:%s\r\n" % value)
|