mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +00:00
bpo-38185: Fixed case-insensitive string comparison in sqlite3.Row indexing. (GH-16190)
This commit is contained in:
parent
dfd34a9cd5
commit
f669581a95
3 changed files with 50 additions and 38 deletions
|
|
@ -76,16 +76,38 @@ PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
|
|||
return item;
|
||||
}
|
||||
|
||||
static int
|
||||
equal_ignore_case(PyObject *left, PyObject *right)
|
||||
{
|
||||
int eq = PyObject_RichCompareBool(left, right, Py_EQ);
|
||||
if (eq) { /* equal or error */
|
||||
return eq;
|
||||
}
|
||||
if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) {
|
||||
return 0;
|
||||
}
|
||||
if (!PyUnicode_IS_ASCII(left) || !PyUnicode_IS_ASCII(right)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_ssize_t len = PyUnicode_GET_LENGTH(left);
|
||||
if (PyUnicode_GET_LENGTH(right) != len) {
|
||||
return 0;
|
||||
}
|
||||
const Py_UCS1 *p1 = PyUnicode_1BYTE_DATA(left);
|
||||
const Py_UCS1 *p2 = PyUnicode_1BYTE_DATA(right);
|
||||
for (; len; len--, p1++, p2++) {
|
||||
if (Py_TOLOWER(*p1) != Py_TOLOWER(*p2)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
|
||||
{
|
||||
Py_ssize_t _idx;
|
||||
const char *key;
|
||||
Py_ssize_t nitems, i;
|
||||
const char *compare_key;
|
||||
|
||||
const char *p1;
|
||||
const char *p2;
|
||||
|
||||
PyObject* item;
|
||||
|
||||
if (PyLong_Check(idx)) {
|
||||
|
|
@ -98,44 +120,22 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
|
|||
Py_XINCREF(item);
|
||||
return item;
|
||||
} else if (PyUnicode_Check(idx)) {
|
||||
key = PyUnicode_AsUTF8(idx);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
nitems = PyTuple_Size(self->description);
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
PyObject *obj;
|
||||
obj = PyTuple_GET_ITEM(self->description, i);
|
||||
obj = PyTuple_GET_ITEM(obj, 0);
|
||||
compare_key = PyUnicode_AsUTF8(obj);
|
||||
if (!compare_key) {
|
||||
int eq = equal_ignore_case(idx, obj);
|
||||
if (eq < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p1 = key;
|
||||
p2 = compare_key;
|
||||
|
||||
while (1) {
|
||||
if ((*p1 == (char)0) || (*p2 == (char)0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*p1 | 0x20) != (*p2 | 0x20)) {
|
||||
break;
|
||||
}
|
||||
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
|
||||
if ((*p1 == (char)0) && (*p2 == (char)0)) {
|
||||
if (eq) {
|
||||
/* found item */
|
||||
item = PyTuple_GetItem(self->data, i);
|
||||
Py_INCREF(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_IndexError, "No item with that key");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue