Skip to content

Commit 2862c30

Browse files
authored
Fix crash when extending from proxy (#1100)
1 parent 7fe5fba commit 2862c30

5 files changed

Lines changed: 28 additions & 1 deletion

File tree

CHANGES/1100.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a crash when extending a multidict from multidict proxy if C Extensions were used.

multidict/_multidict.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,11 @@ _multidict_extend_with_args(MultiDictObject *self, PyObject *arg,
227227

228228
if (PyObject_HasAttrString(arg, "items")) {
229229
if (_MultiDict_Check(arg)) {
230-
arg_items = multidict_items((MultiDictObject*)arg);
230+
if (MultiDict_CheckExact(arg) || CIMultiDict_CheckExact(arg)) {
231+
arg_items = multidict_items((MultiDictObject*)arg);
232+
} else if (MultiDictProxy_CheckExact(arg) || CIMultiDictProxy_CheckExact(arg)) {
233+
arg_items = multidict_items(((MultiDictProxyObject*)arg)->md);
234+
}
231235
} else {
232236
arg_items = PyMapping_Items(arg);
233237
}

multidict/_multilib/iter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ multidict_items_iter_iternext(MultidictIter *self)
8181
return NULL;
8282
}
8383
if (res == 0) {
84+
Py_CLEAR(key);
85+
Py_CLEAR(value);
8486
PyErr_SetNone(PyExc_StopIteration);
8587
return NULL;
8688
}

multidict/_multilib/pair_list.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,22 @@ pair_list_next(pair_list_t *list, pair_list_pos_t *pos,
421421
PyObject **pkey, PyObject **pvalue)
422422
{
423423
if (pos->pos >= list->size) {
424+
if (pkey) {
425+
*pkey = NULL;
426+
}
427+
if (pvalue) {
428+
*pvalue = NULL;
429+
}
424430
return 0;
425431
}
426432

427433
if (pos->version != list->version) {
434+
if (pkey) {
435+
*pkey = NULL;
436+
}
437+
if (pvalue) {
438+
*pvalue = NULL;
439+
}
428440
PyErr_SetString(PyExc_RuntimeError, "MultiDict changed during iteration");
429441
return -1;
430442
}

tests/test_multidict.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,14 @@ def test_basics(self, cls: type[CIMultiDict[str]]) -> None:
793793
with pytest.raises(KeyError, match="key2"):
794794
d.getone("key2")
795795

796+
def test_from_md_and_kwds(self, cls: type[CIMultiDict[str]]) -> None:
797+
d = cls([("KEY", "value1")])
798+
d2 = cls(d, KEY="value2")
799+
800+
print(type(d))
801+
802+
assert list(d2.items()) == [("KEY", "value1"), ("KEY", "value2")]
803+
796804
def test_getall(self, cls: type[CIMultiDict[str]]) -> None:
797805
d = cls([("KEY", "value1")], KEY="value2")
798806

0 commit comments

Comments
 (0)