be more robust against the filters list changing under us (closes #24096)
diff --git a/Python/_warnings.c b/Python/_warnings.c
index f33e477..d274789 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -98,7 +98,7 @@
 }
 
 
-/* The item is a borrowed reference. */
+/* The item is a new reference. */
 static const char *
 get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
            PyObject *module, PyObject **item)
@@ -129,14 +129,15 @@
         Py_ssize_t ln;
         int is_subclass, good_msg, good_mod;
 
-        tmp_item = *item = PyList_GET_ITEM(_filters, i);
-        if (PyTuple_Size(tmp_item) != 5) {
+        tmp_item = PyList_GET_ITEM(_filters, i);
+        if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
             PyErr_Format(PyExc_ValueError,
                          MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
             return NULL;
         }
 
         /* Python code: action, msg, cat, mod, ln = item */
+        Py_INCREF(tmp_item);
         action = PyTuple_GET_ITEM(tmp_item, 0);
         msg = PyTuple_GET_ITEM(tmp_item, 1);
         cat = PyTuple_GET_ITEM(tmp_item, 2);
@@ -148,15 +149,23 @@
         is_subclass = PyObject_IsSubclass(category, cat);
         ln = PyLong_AsSsize_t(ln_obj);
         if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
-            (ln == -1 && PyErr_Occurred()))
+            (ln == -1 && PyErr_Occurred())) {
+            Py_DECREF(tmp_item);
             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);
+        }
+
+        Py_DECREF(tmp_item);
     }
 
     action = get_default_action();
     if (action != NULL) {
+        Py_INCREF(Py_None);
+        *item = Py_None;
         return _PyUnicode_AsString(action);
     }
 
@@ -295,7 +304,7 @@
               PyObject *module, PyObject *registry, PyObject *sourceline)
 {
     PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
-    PyObject *item = Py_None;
+    PyObject *item = NULL;
     const char *action;
     int rc;
 
@@ -436,6 +445,7 @@
     Py_INCREF(result);
 
  cleanup:
+    Py_XDECREF(item);
     Py_XDECREF(key);
     Py_XDECREF(text);
     Py_XDECREF(lineno_obj);