Skip to content

Commit be257bc

Browse files
[2.7] bpo-38175: Fix a memory leak in comparison of sqlite3.Row objects. (GH-16155). (GH-16215)
(cherry picked from commit 8debfa5)
1 parent 5d55d52 commit be257bc

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

Lib/sqlite3/test/factory.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,19 +159,24 @@ def CheckSqliteRowHashCmp(self):
159159
row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()
160160
row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
161161
row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
162+
row_4 = self.con.execute("select 1 as b, 2 as a").fetchone()
163+
row_5 = self.con.execute("select 2 as b, 1 as a").fetchone()
162164

163-
self.assertEqual(row_1, row_1)
164-
self.assertEqual(row_1, row_2)
165-
self.assertTrue(row_2 != row_3)
165+
self.assertTrue(row_1 == row_1)
166+
self.assertTrue(row_1 == row_2)
167+
self.assertFalse(row_1 == row_3)
168+
self.assertFalse(row_1 == row_4)
169+
self.assertFalse(row_1 == row_5)
170+
self.assertFalse(row_1 == object())
166171

167172
self.assertFalse(row_1 != row_1)
168173
self.assertFalse(row_1 != row_2)
169-
self.assertFalse(row_2 == row_3)
174+
self.assertTrue(row_1 != row_3)
175+
self.assertTrue(row_1 != row_4)
176+
self.assertTrue(row_1 != row_5)
177+
self.assertTrue(row_1 != object())
170178

171-
self.assertEqual(row_1, row_2)
172179
self.assertEqual(hash(row_1), hash(row_2))
173-
self.assertNotEqual(row_1, row_3)
174-
self.assertNotEqual(hash(row_1), hash(row_3))
175180

176181
def CheckSqliteRowAsSequence(self):
177182
""" Checks if the row object can act like a sequence """
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a memory leak in comparison of :class:`sqlite3.Row` objects.

Modules/_sqlite/row.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,16 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
199199
Py_INCREF(Py_NotImplemented);
200200
return Py_NotImplemented;
201201
}
202-
if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
202+
if (PyObject_TypeCheck(_other, &pysqlite_RowType)) {
203203
pysqlite_Row *other = (pysqlite_Row *)_other;
204-
PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
205-
if ((opid == Py_EQ && res == Py_True)
206-
|| (opid == Py_NE && res == Py_False)) {
207-
Py_DECREF(res);
204+
int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
205+
if (eq < 0) {
206+
return NULL;
207+
}
208+
if (eq) {
208209
return PyObject_RichCompare(self->data, other->data, opid);
209210
}
211+
return PyBool_FromLong(opid != Py_EQ);
210212
}
211213
Py_INCREF(Py_NotImplemented);
212214
return Py_NotImplemented;

0 commit comments

Comments
 (0)