Skip to content

Commit 01b58de

Browse files
committed
gh-152405 Safer mapping proxy comparisons
Essentially: * if `w` is a mapping proxy hen unwrap it. * if `w` uses the dict comparison operator then use that. * otherwise return NOT_IMPLEMENTED (on the basis that it's likely that `w`'s rich comparison can do it through the standard mapping interface.
1 parent 499d31f commit 01b58de

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

Objects/descrobject.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,11 +1232,21 @@ mappingproxy_traverse(PyObject *self, visitproc visit, void *arg)
12321232
static PyObject *
12331233
mappingproxy_richcompare(PyObject *self, PyObject *w, int op)
12341234
{
1235-
mappingproxyobject *v = (mappingproxyobject *)self;
12361235
if (op == Py_EQ || op == Py_NE) {
1237-
return PyObject_RichCompare(v->mapping, w, op);
1236+
mappingproxyobject *v = (mappingproxyobject *)self;
1237+
if (Py_TYPE(w) == Py_TYPE(self)) {
1238+
w = ((mappingproxyobject *)w)->mapping;
1239+
}
1240+
1241+
if (PyAnyDict_CheckExact(w) || (PyAnyDict_Check(w) && Py_TYPE(w)->tp_richcompare == PyDict_Type.tp_richcompare)) {
1242+
return PyObject_RichCompare(v->mapping, w, op);
1243+
}
1244+
if (PyFrozenDict_CheckExact(v->mapping)) {
1245+
// immutable - safe to foward.
1246+
return PyObject_RichCompare(v->mapping, w, op);
1247+
}
12381248
}
1239-
Py_RETURN_NOTIMPLEMENTED;
1249+
Py_RETURN_NOTIMPLEMENTED; // Defer to w's richcompare
12401250
}
12411251

12421252
static int

0 commit comments

Comments
 (0)