diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-07-29 07:47:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 07:47:56 (GMT) |
commit | 5269c091458c5ea76eb625e4fabc9980b6309266 (patch) | |
tree | 2c39bdae29af27e9232facd337a41c5163bf0538 /Modules/_sqlite | |
parent | 8d0647485db5af2a0f0929d6509479ca45f1281b (diff) | |
download | cpython-5269c091458c5ea76eb625e4fabc9980b6309266.zip cpython-5269c091458c5ea76eb625e4fabc9980b6309266.tar.gz cpython-5269c091458c5ea76eb625e4fabc9980b6309266.tar.bz2 |
bpo-44688: Remove ASCII limitation from `sqlite3` collation names (GH-27395)
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r-- | Modules/_sqlite/clinic/connection.c.h | 16 | ||||
-rw-r--r-- | Modules/_sqlite/connection.c | 63 |
2 files changed, 22 insertions, 57 deletions
diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index ec0a43a..1626e1c 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -722,13 +722,14 @@ PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, static PyObject * pysqlite_connection_create_collation_impl(pysqlite_Connection *self, - PyObject *name, PyObject *callable); + const char *name, + PyObject *callable); static PyObject * pysqlite_connection_create_collation(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *name; + const char *name; PyObject *callable; if (!_PyArg_CheckPositional("create_collation", nargs, 2, 2)) { @@ -738,10 +739,15 @@ pysqlite_connection_create_collation(pysqlite_Connection *self, PyObject *const _PyArg_BadArgument("create_collation", "argument 1", "str", args[0]); goto exit; } - if (PyUnicode_READY(args[0]) == -1) { + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - name = args[0]; callable = args[1]; return_value = pysqlite_connection_create_collation_impl(self, name, callable); @@ -811,4 +817,4 @@ exit: #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=30f11f2d8f09bdf0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a7a899c4e41381ac input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index af093c3..85b666a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1720,7 +1720,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, /*[clinic input] _sqlite3.Connection.create_collation as pysqlite_connection_create_collation - name: unicode + name: str callback as callable: object / @@ -1729,61 +1729,26 @@ Creates a collation function. Non-standard. static PyObject * pysqlite_connection_create_collation_impl(pysqlite_Connection *self, - PyObject *name, PyObject *callable) -/*[clinic end generated code: output=0f63b8995565ae22 input=5c3898813a776cf2]*/ + const char *name, + PyObject *callable) +/*[clinic end generated code: output=a4ceaff957fdef9a input=301647aab0f2fb1d]*/ { - PyObject* uppercase_name = 0; - Py_ssize_t i, len; - _Py_IDENTIFIER(upper); - const char *uppercase_name_str; - int rc; - unsigned int kind; - const void *data; - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - goto finally; - } - - uppercase_name = _PyObject_CallMethodIdOneArg((PyObject *)&PyUnicode_Type, - &PyId_upper, name); - if (!uppercase_name) { - goto finally; - } - - if (PyUnicode_READY(uppercase_name)) - goto finally; - len = PyUnicode_GET_LENGTH(uppercase_name); - kind = PyUnicode_KIND(uppercase_name); - data = PyUnicode_DATA(uppercase_name); - for (i=0; i<len; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - if ((ch >= '0' && ch <= '9') - || (ch >= 'A' && ch <= 'Z') - || (ch == '_')) - { - continue; - } else { - PyErr_SetString(self->ProgrammingError, - "invalid character in collation name"); - goto finally; - } + return NULL; } - uppercase_name_str = PyUnicode_AsUTF8(uppercase_name); - if (!uppercase_name_str) - goto finally; - + int rc; int flags = SQLITE_UTF8; if (callable == Py_None) { - rc = sqlite3_create_collation_v2(self->db, uppercase_name_str, flags, + rc = sqlite3_create_collation_v2(self->db, name, flags, NULL, NULL, NULL); } else { if (!PyCallable_Check(callable)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); - goto finally; + return NULL; } - rc = sqlite3_create_collation_v2(self->db, uppercase_name_str, flags, + rc = sqlite3_create_collation_v2(self->db, name, flags, Py_NewRef(callable), &pysqlite_collation_callback, &_destructor); @@ -1798,16 +1763,10 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self, Py_DECREF(callable); } _pysqlite_seterror(self->db); - goto finally; - } - -finally: - Py_XDECREF(uppercase_name); - - if (PyErr_Occurred()) { return NULL; } - return Py_NewRef(Py_None); + + Py_RETURN_NONE; } /*[clinic input] |