Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf669581

Browse files
bpo-38185: Fixed case-insensitive string comparison in sqlite3.Row indexing. (GH-16190)
1 parentdfd34a9 commitf669581

File tree

3 files changed

+50
-38
lines changed

3 files changed

+50
-38
lines changed

‎Lib/sqlite3/test/factory.py‎

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,14 @@ def CheckCustomFactory(self):
9898

9999
defCheckSqliteRowIndex(self):
100100
self.con.row_factory=sqlite.Row
101-
row=self.con.execute("select 1 asa, 2 as b").fetchone()
101+
row=self.con.execute("select 1 asa_1, 2 as b").fetchone()
102102
self.assertIsInstance(row,sqlite.Row)
103103

104-
col1,col2=row["a"],row["b"]
105-
self.assertEqual(col1,1,"by name: wrong result for column 'a'")
106-
self.assertEqual(col2,2,"by name: wrong result for column 'a'")
104+
self.assertEqual(row["a_1"],1,"by name: wrong result for column 'a_1'")
105+
self.assertEqual(row["b"],2,"by name: wrong result for column 'b'")
107106

108-
col1,col2=row["A"],row["B"]
109-
self.assertEqual(col1,1,"by name: wrong result for column 'A'")
110-
self.assertEqual(col2,2,"by name: wrong result for column 'B'")
107+
self.assertEqual(row["A_1"],1,"by name: wrong result for column 'A_1'")
108+
self.assertEqual(row["B"],2,"by name: wrong result for column 'B'")
111109

112110
self.assertEqual(row[0],1,"by index: wrong result for column 0")
113111
self.assertEqual(row[1],2,"by index: wrong result for column 1")
@@ -116,13 +114,26 @@ def CheckSqliteRowIndex(self):
116114

117115
withself.assertRaises(IndexError):
118116
row['c']
117+
withself.assertRaises(IndexError):
118+
row['a_\x11']
119+
withself.assertRaises(IndexError):
120+
row['a\x7f1']
119121
withself.assertRaises(IndexError):
120122
row[2]
121123
withself.assertRaises(IndexError):
122124
row[-3]
123125
withself.assertRaises(IndexError):
124126
row[2**1000]
125127

128+
defCheckSqliteRowIndexUnicode(self):
129+
self.con.row_factory=sqlite.Row
130+
row=self.con.execute("select 1 as\xff").fetchone()
131+
self.assertEqual(row["\xff"],1)
132+
withself.assertRaises(IndexError):
133+
row['\u0178']
134+
withself.assertRaises(IndexError):
135+
row['\xdf']
136+
126137
defCheckSqliteRowSlice(self):
127138
# A sqlite.Row can be sliced like a list.
128139
self.con.row_factory=sqlite.Row
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed case-insensitive string comparison in:class:`sqlite3.Row` indexing.

‎Modules/_sqlite/row.c‎

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,38 @@ PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
7676
returnitem;
7777
}
7878

79+
staticint
80+
equal_ignore_case(PyObject*left,PyObject*right)
81+
{
82+
inteq=PyObject_RichCompareBool(left,right,Py_EQ);
83+
if (eq) {/* equal or error */
84+
returneq;
85+
}
86+
if (!PyUnicode_Check(left)|| !PyUnicode_Check(right)) {
87+
return0;
88+
}
89+
if (!PyUnicode_IS_ASCII(left)|| !PyUnicode_IS_ASCII(right)) {
90+
return0;
91+
}
92+
93+
Py_ssize_tlen=PyUnicode_GET_LENGTH(left);
94+
if (PyUnicode_GET_LENGTH(right)!=len) {
95+
return0;
96+
}
97+
constPy_UCS1*p1=PyUnicode_1BYTE_DATA(left);
98+
constPy_UCS1*p2=PyUnicode_1BYTE_DATA(right);
99+
for (;len;len--,p1++,p2++) {
100+
if (Py_TOLOWER(*p1)!=Py_TOLOWER(*p2)) {
101+
return0;
102+
}
103+
}
104+
return1;
105+
}
106+
79107
PyObject*pysqlite_row_subscript(pysqlite_Row*self,PyObject*idx)
80108
{
81109
Py_ssize_t_idx;
82-
constchar*key;
83110
Py_ssize_tnitems,i;
84-
constchar*compare_key;
85-
86-
constchar*p1;
87-
constchar*p2;
88-
89111
PyObject*item;
90112

91113
if (PyLong_Check(idx)) {
@@ -98,44 +120,22 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
98120
Py_XINCREF(item);
99121
returnitem;
100122
}elseif (PyUnicode_Check(idx)) {
101-
key=PyUnicode_AsUTF8(idx);
102-
if (key==NULL)
103-
returnNULL;
104-
105123
nitems=PyTuple_Size(self->description);
106124

107125
for (i=0;i<nitems;i++) {
108126
PyObject*obj;
109127
obj=PyTuple_GET_ITEM(self->description,i);
110128
obj=PyTuple_GET_ITEM(obj,0);
111-
compare_key=PyUnicode_AsUTF8(obj);
112-
if (!compare_key) {
129+
inteq=equal_ignore_case(idx,obj);
130+
if (eq<0) {
113131
returnNULL;
114132
}
115-
116-
p1=key;
117-
p2=compare_key;
118-
119-
while (1) {
120-
if ((*p1== (char)0)|| (*p2== (char)0)) {
121-
break;
122-
}
123-
124-
if ((*p1 |0x20)!= (*p2 |0x20)) {
125-
break;
126-
}
127-
128-
p1++;
129-
p2++;
130-
}
131-
132-
if ((*p1== (char)0)&& (*p2== (char)0)) {
133+
if (eq) {
133134
/* found item */
134135
item=PyTuple_GetItem(self->data,i);
135136
Py_INCREF(item);
136137
returnitem;
137138
}
138-
139139
}
140140

141141
PyErr_SetString(PyExc_IndexError,"No item with that key");

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp