be more robust against the filters list changing under us (closes #24096)
This commit is contained in:
parent
501182a47b
commit
deff2b76ec
|
@ -185,6 +185,18 @@ class FilterTests(BaseTest):
|
||||||
self.assertEqual(str(w[-1].message), text)
|
self.assertEqual(str(w[-1].message), text)
|
||||||
self.assertTrue(w[-1].category is UserWarning)
|
self.assertTrue(w[-1].category is UserWarning)
|
||||||
|
|
||||||
|
def test_mutate_filter_list(self):
|
||||||
|
class X:
|
||||||
|
def match(self, a):
|
||||||
|
L[:] = []
|
||||||
|
|
||||||
|
L = [("default",X(),UserWarning,X(),0) for i in range(2)]
|
||||||
|
with original_warnings.catch_warnings(record=True,
|
||||||
|
module=self.module) as w:
|
||||||
|
self.module.filters = L
|
||||||
|
self.module.warn_explicit(UserWarning("b"), None, "f.py", 42)
|
||||||
|
self.assertEqual(str(w[-1].message), "b")
|
||||||
|
|
||||||
class CFilterTests(FilterTests, unittest.TestCase):
|
class CFilterTests(FilterTests, unittest.TestCase):
|
||||||
module = c_warnings
|
module = c_warnings
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.3.7?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #24096: Make warnings.warn_explicit more robust against mutation of the
|
||||||
|
warnings.filters list.
|
||||||
|
|
||||||
- Issue #24044: Fix possible null pointer dereference in list.sort in out of
|
- Issue #24044: Fix possible null pointer dereference in list.sort in out of
|
||||||
memory conditions.
|
memory conditions.
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ get_default_action(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The item is a borrowed reference. */
|
/* The item is a new reference. */
|
||||||
static const char *
|
static const char *
|
||||||
get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
||||||
PyObject *module, PyObject **item)
|
PyObject *module, PyObject **item)
|
||||||
|
@ -129,14 +129,15 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
||||||
Py_ssize_t ln;
|
Py_ssize_t ln;
|
||||||
int is_subclass, good_msg, good_mod;
|
int is_subclass, good_msg, good_mod;
|
||||||
|
|
||||||
tmp_item = *item = PyList_GET_ITEM(_filters, i);
|
tmp_item = PyList_GET_ITEM(_filters, i);
|
||||||
if (PyTuple_Size(tmp_item) != 5) {
|
if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
|
MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Python code: action, msg, cat, mod, ln = item */
|
/* Python code: action, msg, cat, mod, ln = item */
|
||||||
|
Py_INCREF(tmp_item);
|
||||||
action = PyTuple_GET_ITEM(tmp_item, 0);
|
action = PyTuple_GET_ITEM(tmp_item, 0);
|
||||||
msg = PyTuple_GET_ITEM(tmp_item, 1);
|
msg = PyTuple_GET_ITEM(tmp_item, 1);
|
||||||
cat = PyTuple_GET_ITEM(tmp_item, 2);
|
cat = PyTuple_GET_ITEM(tmp_item, 2);
|
||||||
|
@ -148,15 +149,23 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
|
||||||
is_subclass = PyObject_IsSubclass(category, cat);
|
is_subclass = PyObject_IsSubclass(category, cat);
|
||||||
ln = PyLong_AsSsize_t(ln_obj);
|
ln = PyLong_AsSsize_t(ln_obj);
|
||||||
if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
|
if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
|
||||||
(ln == -1 && PyErr_Occurred()))
|
(ln == -1 && PyErr_Occurred())) {
|
||||||
|
Py_DECREF(tmp_item);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
|
if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
|
||||||
|
*item = tmp_item;
|
||||||
return _PyUnicode_AsString(action);
|
return _PyUnicode_AsString(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(tmp_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
action = get_default_action();
|
action = get_default_action();
|
||||||
if (action != NULL) {
|
if (action != NULL) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
*item = Py_None;
|
||||||
return _PyUnicode_AsString(action);
|
return _PyUnicode_AsString(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +304,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
||||||
PyObject *module, PyObject *registry, PyObject *sourceline)
|
PyObject *module, PyObject *registry, PyObject *sourceline)
|
||||||
{
|
{
|
||||||
PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
|
PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
|
||||||
PyObject *item = Py_None;
|
PyObject *item = NULL;
|
||||||
const char *action;
|
const char *action;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -436,6 +445,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
||||||
Py_INCREF(result);
|
Py_INCREF(result);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Py_XDECREF(item);
|
||||||
Py_XDECREF(key);
|
Py_XDECREF(key);
|
||||||
Py_XDECREF(text);
|
Py_XDECREF(text);
|
||||||
Py_XDECREF(lineno_obj);
|
Py_XDECREF(lineno_obj);
|
||||||
|
|
Loading…
Reference in New Issue