Permalink
Browse files

SQLite can cope with text with embedded NUL. We can now, too.

  • Loading branch information...
1 parent 1d6feef commit 361e17a135c462a426f4741e242378d06e22a1cc @ghaering ghaering committed Jul 5, 2011
Showing with 24 additions and 14 deletions.
  1. +10 −0 lib/test/types.py
  2. +10 −12 src/cursor.c
  3. +4 −2 src/statement.c
View
@@ -102,6 +102,16 @@ def CheckNonUtf8_TextFactoryOptimizedUnicode(self):
finally:
self.con.text_factory = orig_text_factory
+ def CheckBinaryString(self):
+ bin_string = u"foo\x00bar"
+ self.cur.execute("select ?", (bin_string,))
+ self.assertEqual(self.cur.fetchone()[0], bin_string)
+
+ def CheckBinaryByteString(self):
+ bin_string = "bla\x00bla"
+ self.cur.execute("select ?", (bin_string,))
+ self.assertEqual(self.cur.fetchone()[0], bin_string)
+
class DeclTypesTests(unittest.TestCase):
class Foo:
def __init__(self, _val):
View
@@ -268,29 +268,26 @@ PyObject* _pysqlite_build_column_name(const char* colname)
}
}
-PyObject* pysqlite_unicode_from_string(const char* val_str, int optimize)
+static PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t nbytes, int optimize)
{
- const char* check;
int is_ascii = 0;
+ int i;
if (optimize) {
is_ascii = 1;
- check = val_str;
- while (*check) {
- if (*check & 0x80) {
+ for (i = 0; i < nbytes; i++) {
+ if (val_str[i] & 0x80) {
is_ascii = 0;
break;
}
-
- check++;
}
}
if (is_ascii) {
- return PyString_FromString(val_str);
+ return PyString_FromStringAndSize(val_str, nbytes);
} else {
- return PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
+ return PyUnicode_DecodeUTF8(val_str, nbytes, NULL);
}
}
@@ -331,6 +328,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
}
for (i = 0; i < numcols; i++) {
+ nbytes = sqlite3_column_bytes(self->statement->st, i);
+
if (self->connection->detect_types) {
converter = PyList_GetItem(self->row_cast_map, i);
if (!converter) {
@@ -341,7 +340,6 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
}
if (converter != Py_None) {
- nbytes = sqlite3_column_bytes(self->statement->st, i);
val_str = (const char*)sqlite3_column_blob(self->statement->st, i);
if (!val_str) {
Py_INCREF(Py_None);
@@ -378,7 +376,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type)
|| (self->connection->text_factory == pysqlite_OptimizedUnicode)) {
- converted = pysqlite_unicode_from_string(val_str,
+ converted = pysqlite_unicode_from_string(val_str, nbytes,
self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0);
if (!converted) {
@@ -391,7 +389,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
PyErr_SetString(pysqlite_OperationalError, buf);
}
} else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
- converted = PyString_FromString(val_str);
+ converted = PyString_FromStringAndSize(val_str, nbytes);
} else {
converted = PyObject_CallFunction(self->connection->text_factory, "s", val_str);
}
View
@@ -167,12 +167,14 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
break;
case TYPE_STRING:
string = PyString_AS_STRING(parameter);
- rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+ buflen = PyString_Size(parameter);
+ rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT);
break;
case TYPE_UNICODE:
stringval = PyUnicode_AsUTF8String(parameter);
string = PyString_AsString(stringval);
- rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
+ buflen = PyString_Size(stringval);
+ rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT);
Py_DECREF(stringval);
break;
case TYPE_BUFFER:

0 comments on commit 361e17a

Please sign in to comment.