diff --git a/Lib/sqlite3/test/factory.py b/Lib/sqlite3/test/factory.py index 8a77d5d7095..9469d79c2eb 100644 --- a/Lib/sqlite3/test/factory.py +++ b/Lib/sqlite3/test/factory.py @@ -1,7 +1,7 @@ #-*- coding: ISO-8859-1 -*- # pysqlite2/test/factory.py: tests for the various factories in pysqlite # -# Copyright (C) 2005 Gerhard Häring +# Copyright (C) 2005-2007 Gerhard Häring # # This file is part of pysqlite. # diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 31bf289190e..8a1130de88f 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -2,7 +2,7 @@ # pysqlite2/test/userfunctions.py: tests for user-defined functions and # aggregates. # -# Copyright (C) 2005 Gerhard Häring +# Copyright (C) 2005-2007 Gerhard Häring # # This file is part of pysqlite. # diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index cfbb5eb18f5..85118fc78e4 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -1,6 +1,6 @@ /* cache .c - a LRU cache * - * Copyright (C) 2004-2006 Gerhard Häring + * Copyright (C) 2004-2007 Gerhard Häring * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 158bf5a894f..d6f7f13296e 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -1,6 +1,6 @@ /* cache.h - definitions for the LRU cache * - * Copyright (C) 2004-2006 Gerhard Häring + * Copyright (C) 2004-2007 Gerhard Häring * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 566e4ff0daa..2681fc79f5f 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -424,10 +424,14 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* PyObject* descriptor; PyObject* second_argument = NULL; long rowcount = 0; + int allow_8bit_chars; if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { return NULL; } + /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */ + allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) && + (self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode)); Py_XDECREF(self->next_row); self->next_row = NULL; @@ -592,7 +596,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* pysqlite_statement_mark_dirty(self->statement); - pysqlite_statement_bind_parameters(self->statement, parameters); + pysqlite_statement_bind_parameters(self->statement, parameters, allow_8bit_chars); if (PyErr_Occurred()) { goto error; } diff --git a/Modules/_sqlite/prepare_protocol.h b/Modules/_sqlite/prepare_protocol.h index 4c1e4f34b80..153472e9dea 100644 --- a/Modules/_sqlite/prepare_protocol.h +++ b/Modules/_sqlite/prepare_protocol.h @@ -1,6 +1,6 @@ /* prepare_protocol.h - the protocol for preparing values for SQLite * - * Copyright (C) 2005 Gerhard Häring + * Copyright (C) 2005-2007 Gerhard Häring * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/row.h b/Modules/_sqlite/row.h index b92225b4619..8ed69aee214 100644 --- a/Modules/_sqlite/row.h +++ b/Modules/_sqlite/row.h @@ -1,6 +1,6 @@ /* row.h - an enhanced tuple for database rows * - * Copyright (C) 2005 Gerhard Häring + * Copyright (C) 2005-2007 Gerhard Häring * * This file is part of pysqlite. * diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 556ea01f41a..d8d91140c16 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -96,7 +96,7 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con return rc; } -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) +int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars) { int rc = SQLITE_OK; long longval; @@ -108,6 +108,7 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec Py_ssize_t buflen; PyObject* stringval; parameter_type paramtype; + char* c; if (parameter == Py_None) { rc = sqlite3_bind_null(self->st, pos); @@ -140,6 +141,17 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec paramtype = TYPE_UNKNOWN; } + if (paramtype == TYPE_STRING && !allow_8bit_chars) { + string = PyString_AS_STRING(parameter); + for (c = string; *c != 0; c++) { + if (*c & 0x80) { + PyErr_SetString(pysqlite_ProgrammingError, "You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings."); + rc = -1; + goto final; + } + } + } + switch (paramtype) { case TYPE_INT: longval = PyInt_AsLong(parameter); @@ -197,7 +209,7 @@ static int _need_adapt(PyObject* obj) } } -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters) +void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars) { PyObject* current_param; PyObject* adapted; @@ -251,11 +263,13 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } } - rc = pysqlite_statement_bind_parameter(self, i + 1, adapted); + rc = pysqlite_statement_bind_parameter(self, i + 1, adapted, allow_8bit_chars); Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i); + if (!PyErr_Occurred()) { + PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i); + } return; } } @@ -294,11 +308,13 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } } - rc = pysqlite_statement_bind_parameter(self, i, adapted); + rc = pysqlite_statement_bind_parameter(self, i, adapted, allow_8bit_chars); Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name); + if (!PyErr_Occurred()) { + PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name); + } return; } } diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 10b88235177..bfa20916246 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -1,6 +1,6 @@ /* statement.h - definitions for the statement type * - * Copyright (C) 2005 Gerhard Häring + * Copyright (C) 2005-2007 Gerhard Häring * * This file is part of pysqlite. * @@ -46,8 +46,8 @@ extern PyTypeObject pysqlite_StatementType; int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); void pysqlite_statement_dealloc(pysqlite_Statement* self); -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); +int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars); +void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters, int allow_8bit_chars); int pysqlite_statement_recompile(pysqlite_Statement* self, PyObject* parameters); int pysqlite_statement_finalize(pysqlite_Statement* self); diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index 6c343298e26..179be784954 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -1,6 +1,6 @@ /* util.h - various utility functions * - * Copyright (C) 2005-2006 Gerhard Häring + * Copyright (C) 2005-2007 Gerhard Häring * * This file is part of pysqlite. *