diff options
-rw-r--r-- | Lib/sqlite3/test/regression.py | 7 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/_sqlite/connection.c | 17 |
3 files changed, 22 insertions, 5 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index da44551..5e315fa 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -183,6 +183,13 @@ class RegressionTests(unittest.TestCase): """ self.assertRaises(sqlite.Warning, self.con, 1) + def CheckCollation(self): + def collation_cb(a, b): + return 1 + self.assertRaises(sqlite.ProgrammingError, self.con.create_collation, + # Lone surrogate cannot be encoded to the default encoding (utf8) + "\uDC80", collation_cb) + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") return unittest.TestSuite((regression_suite,)) @@ -33,6 +33,9 @@ Core and Builtins Library ------- +- Issue #8195: Fix a crash in sqlite Connection.create_collation() if the + collation name contains a surrogate character. + - Issue #8484: Load all ciphers and digest algorithms when initializing the _ssl extension, such that verification of some SSL certificates doesn't fail because of an "unknown algorithm". diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 4b8088d..11fb4ac 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1228,7 +1228,9 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) PyObject* uppercase_name = 0; PyObject* name; PyObject* retval; - char* chk; + Py_UNICODE* chk; + Py_ssize_t i, len; + char *uppercase_name_str; int rc; if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { @@ -1244,19 +1246,24 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - chk = _PyUnicode_AsString(uppercase_name); - while (*chk) { + len = PyUnicode_GET_SIZE(uppercase_name); + chk = PyUnicode_AS_UNICODE(uppercase_name); + for (i=0; i<len; i++, chk++) { if ((*chk >= '0' && *chk <= '9') || (*chk >= 'A' && *chk <= 'Z') || (*chk == '_')) { - chk++; + continue; } else { PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name"); goto finally; } } + uppercase_name_str = _PyUnicode_AsString(uppercase_name); + if (!uppercase_name_str) + goto finally; + if (callable != Py_None && !PyCallable_Check(callable)) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); goto finally; @@ -1269,7 +1276,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) } rc = sqlite3_create_collation(self->db, - _PyUnicode_AsString(uppercase_name), + uppercase_name_str, SQLITE_UTF8, (callable != Py_None) ? callable : NULL, (callable != Py_None) ? pysqlite_collation_callback : NULL); |