summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2010-04-22 11:23:23 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2010-04-22 11:23:23 (GMT)
commit35466c5bcec27fbcdb702f10e2269c6efef978ae (patch)
treebc94214b5e695070279aa6033d8d3936ced02ea4
parent0c2d8b8e51e8bcebd21f8fe33ca0c816e3320c4c (diff)
downloadcpython-35466c5bcec27fbcdb702f10e2269c6efef978ae.zip
cpython-35466c5bcec27fbcdb702f10e2269c6efef978ae.tar.gz
cpython-35466c5bcec27fbcdb702f10e2269c6efef978ae.tar.bz2
Issue #8195: Fix a crash in sqlite Connection.create_collation() if the
collation name contains a surrogate character.
-rw-r--r--Lib/sqlite3/test/regression.py7
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_sqlite/connection.c17
3 files changed, 22 insertions, 5 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py
index 255bd3f..7d0553d 100644
--- a/Lib/sqlite3/test/regression.py
+++ b/Lib/sqlite3/test/regression.py
@@ -274,6 +274,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,))
diff --git a/Misc/NEWS b/Misc/NEWS
index fffe64f..ff93519 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -323,6 +323,9 @@ C-API
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 d916c34..88d6b40 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -1374,7 +1374,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)) {
@@ -1390,19 +1392,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;
@@ -1417,7 +1424,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);