Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 35466c5

Browse files
author
Victor Stinner
committed
Issue #8195: Fix a crash in sqlite Connection.create_collation() if the
collation name contains a surrogate character.
1 parent 0c2d8b8 commit 35466c5

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

Lib/sqlite3/test/regression.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ def CheckConnectionCall(self):
274274
"""
275275
self.assertRaises(sqlite.Warning, self.con, 1)
276276

277+
def CheckCollation(self):
278+
def collation_cb(a, b):
279+
return 1
280+
self.assertRaises(sqlite.ProgrammingError, self.con.create_collation,
281+
# Lone surrogate cannot be encoded to the default encoding (utf8)
282+
"\uDC80", collation_cb)
283+
277284
def suite():
278285
regression_suite = unittest.makeSuite(RegressionTests, "Check")
279286
return unittest.TestSuite((regression_suite,))

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ C-API
323323
Library
324324
-------
325325

326+
- Issue #8195: Fix a crash in sqlite Connection.create_collation() if the
327+
collation name contains a surrogate character.
328+
326329
- Issue #8484: Load all ciphers and digest algorithms when initializing
327330
the _ssl extension, such that verification of some SSL certificates
328331
doesn't fail because of an "unknown algorithm".

Modules/_sqlite/connection.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,9 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
13741374
PyObject* uppercase_name = 0;
13751375
PyObject* name;
13761376
PyObject* retval;
1377-
char* chk;
1377+
Py_UNICODE* chk;
1378+
Py_ssize_t i, len;
1379+
char *uppercase_name_str;
13781380
int rc;
13791381

13801382
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
@@ -1390,19 +1392,24 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
13901392
goto finally;
13911393
}
13921394

1393-
chk = _PyUnicode_AsString(uppercase_name);
1394-
while (*chk) {
1395+
len = PyUnicode_GET_SIZE(uppercase_name);
1396+
chk = PyUnicode_AS_UNICODE(uppercase_name);
1397+
for (i=0; i<len; i++, chk++) {
13951398
if ((*chk >= '0' && *chk <= '9')
13961399
|| (*chk >= 'A' && *chk <= 'Z')
13971400
|| (*chk == '_'))
13981401
{
1399-
chk++;
1402+
continue;
14001403
} else {
14011404
PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name");
14021405
goto finally;
14031406
}
14041407
}
14051408

1409+
uppercase_name_str = _PyUnicode_AsString(uppercase_name);
1410+
if (!uppercase_name_str)
1411+
goto finally;
1412+
14061413
if (callable != Py_None && !PyCallable_Check(callable)) {
14071414
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
14081415
goto finally;
@@ -1417,7 +1424,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args)
14171424
}
14181425

14191426
rc = sqlite3_create_collation(self->db,
1420-
_PyUnicode_AsString(uppercase_name),
1427+
uppercase_name_str,
14211428
SQLITE_UTF8,
14221429
(callable != Py_None) ? callable : NULL,
14231430
(callable != Py_None) ? pysqlite_collation_callback : NULL);

0 commit comments

Comments
 (0)