]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[2.7] bpo-38175: Fix a memory leak in comparison of sqlite3.Row objects. (GH-16155...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 17 Sep 2019 06:56:27 +0000 (09:56 +0300)
committerGitHub <noreply@github.com>
Tue, 17 Sep 2019 06:56:27 +0000 (09:56 +0300)
(cherry picked from commit 8debfa50407107ff2329d01081cdc12d359f1d12)

Lib/sqlite3/test/factory.py
Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst [new file with mode: 0644]
Modules/_sqlite/row.c

index b9e9cd7fd7f41318eb9aaabf5f5e77728aa183ed..b8e0f645a00e3308e75440e06fdeee33cbf568ba 100644 (file)
@@ -159,19 +159,24 @@ class RowFactoryTests(unittest.TestCase):
         row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()
         row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
         row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
+        row_4 = self.con.execute("select 1 as b, 2 as a").fetchone()
+        row_5 = self.con.execute("select 2 as b, 1 as a").fetchone()
 
-        self.assertEqual(row_1, row_1)
-        self.assertEqual(row_1, row_2)
-        self.assertTrue(row_2 != row_3)
+        self.assertTrue(row_1 == row_1)
+        self.assertTrue(row_1 == row_2)
+        self.assertFalse(row_1 == row_3)
+        self.assertFalse(row_1 == row_4)
+        self.assertFalse(row_1 == row_5)
+        self.assertFalse(row_1 == object())
 
         self.assertFalse(row_1 != row_1)
         self.assertFalse(row_1 != row_2)
-        self.assertFalse(row_2 == row_3)
+        self.assertTrue(row_1 != row_3)
+        self.assertTrue(row_1 != row_4)
+        self.assertTrue(row_1 != row_5)
+        self.assertTrue(row_1 != object())
 
-        self.assertEqual(row_1, row_2)
         self.assertEqual(hash(row_1), hash(row_2))
-        self.assertNotEqual(row_1, row_3)
-        self.assertNotEqual(hash(row_1), hash(row_3))
 
     def CheckSqliteRowAsSequence(self):
         """ Checks if the row object can act like a sequence """
diff --git a/Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst b/Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst
new file mode 100644 (file)
index 0000000..6d9f280
--- /dev/null
@@ -0,0 +1 @@
+Fix a memory leak in comparison of :class:`sqlite3.Row` objects.
index 9ebe7b7b81fb4dbd3dbd8def343e4a43637af1fb..c0da329c13eb953bc15beab95372954a1fc1a302 100644 (file)
@@ -199,14 +199,16 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
     }
-    if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
+    if (PyObject_TypeCheck(_other, &pysqlite_RowType)) {
         pysqlite_Row *other = (pysqlite_Row *)_other;
-        PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
-        if ((opid == Py_EQ && res == Py_True)
-            || (opid == Py_NE && res == Py_False)) {
-            Py_DECREF(res);
+        int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
+        if (eq < 0) {
+            return NULL;
+        }
+        if (eq) {
             return PyObject_RichCompare(self->data, other->data, opid);
         }
+        return PyBool_FromLong(opid != Py_EQ);
     }
     Py_INCREF(Py_NotImplemented);
     return Py_NotImplemented;