diff options
Diffstat (limited to 'Modules/_sqlite/cursor.c')
-rw-r--r-- | Modules/_sqlite/cursor.c | 109 |
1 files changed, 93 insertions, 16 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index fe6cff9..e68a275 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -24,6 +24,7 @@ #include "cursor.h" #include "module.h" #include "util.h" +#include "sqlitecompat.h" /* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */ #define INT32_MIN (-2147483647 - 1) @@ -84,6 +85,9 @@ int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs) self->next_row = NULL; self->row_cast_map = PyList_New(0); + if (!self->row_cast_map) { + return -1; + } Py_INCREF(Py_None); self->description = Py_None; @@ -94,6 +98,9 @@ int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs) self->arraysize = 1; self->rowcount = PyInt_FromLong(-1L); + if (!self->rowcount) { + return -1; + } Py_INCREF(Py_None); self->row_factory = Py_None; @@ -126,7 +133,7 @@ void cursor_dealloc(Cursor* self) self->ob_type->tp_free((PyObject*)self); } -void build_row_cast_map(Cursor* self) +int build_row_cast_map(Cursor* self) { int i; const char* type_start = (const char*)-1; @@ -139,10 +146,10 @@ void build_row_cast_map(Cursor* self) PyObject* key; if (!self->connection->detect_types) { - return; + return 0; } - Py_DECREF(self->row_cast_map); + Py_XDECREF(self->row_cast_map); self->row_cast_map = PyList_New(0); for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { @@ -156,6 +163,13 @@ void build_row_cast_map(Cursor* self) type_start = pos + 1; } else if (*pos == ']' && type_start != (const char*)-1) { key = PyString_FromStringAndSize(type_start, pos - type_start); + if (!key) { + /* creating a string failed, but it is too complicated + * to propagate the error here, we just assume there is + * no converter and proceed */ + break; + } + converter = PyDict_GetItem(converters, key); Py_DECREF(key); break; @@ -170,6 +184,9 @@ void build_row_cast_map(Cursor* self) for (pos = decltype;;pos++) { if (*pos == ' ' || *pos == 0) { py_decltype = PyString_FromStringAndSize(decltype, pos - decltype); + if (!py_decltype) { + return -1; + } break; } } @@ -179,18 +196,33 @@ void build_row_cast_map(Cursor* self) } } - if (converter) { - PyList_Append(self->row_cast_map, converter); - } else { - PyList_Append(self->row_cast_map, Py_None); + if (!converter) { + converter = Py_None; + } + + if (PyList_Append(self->row_cast_map, converter) != 0) { + if (converter != Py_None) { + Py_DECREF(converter); + } + Py_XDECREF(self->row_cast_map); + self->row_cast_map = NULL; + + return -1; } } + + return 0; } PyObject* _build_column_name(const char* colname) { const char* pos; + if (!colname) { + Py_INCREF(Py_None); + return Py_None; + } + for (pos = colname;; pos++) { if (*pos == 0 || *pos == ' ') { return PyString_FromStringAndSize(colname, pos - colname); @@ -250,6 +282,9 @@ PyObject* _fetch_one_row(Cursor* self) Py_END_ALLOW_THREADS row = PyTuple_New(numcols); + if (!row) { + return NULL; + } for (i = 0; i < numcols; i++) { if (self->connection->detect_types) { @@ -268,6 +303,9 @@ PyObject* _fetch_one_row(Cursor* self) converted = Py_None; } else { item = PyString_FromString(val_str); + if (!item) { + return NULL; + } converted = PyObject_CallFunction(converter, "O", item); if (!converted) { /* TODO: have a way to log these errors */ @@ -404,10 +442,16 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) if (second_argument == NULL) { second_argument = PyTuple_New(0); + if (!second_argument) { + return NULL; + } } else { Py_INCREF(second_argument); } - PyList_Append(parameters_list, second_argument); + if (PyList_Append(parameters_list, second_argument) != 0) { + Py_DECREF(second_argument); + return NULL; + } Py_DECREF(second_argument); parameters_iter = PyObject_GetIter(parameters_list); @@ -436,6 +480,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) Py_DECREF(self->rowcount); self->rowcount = PyInt_FromLong(-1L); + if (!self->rowcount) { + goto error; + } statement_type = detect_statement_type(operation_cstr); if (self->connection->begin_statement) { @@ -457,6 +504,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) - we better COMMIT first so it works for all cases */ if (self->connection->inTransaction) { func_args = PyTuple_New(0); + if (!func_args) { + goto error; + } result = connection_commit(self->connection, func_args); Py_DECREF(func_args); if (!result) { @@ -471,12 +521,18 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) "You cannot execute SELECT statements in executemany()."); goto error; } + break; } } func_args = PyTuple_New(1); + if (!func_args) { + goto error; + } Py_INCREF(operation); - PyTuple_SetItem(func_args, 0, operation); + if (PyTuple_SetItem(func_args, 0, operation) != 0) { + goto error; + } if (self->statement) { (void)statement_reset(self->statement); @@ -493,6 +549,9 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) if (self->statement->in_use) { Py_DECREF(self->statement); self->statement = PyObject_New(Statement, &StatementType); + if (!self->statement) { + goto error; + } rc = statement_create(self->statement, self->connection, operation); if (rc != SQLITE_OK) { self->statement = 0; @@ -516,7 +575,10 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) goto error; } - build_row_cast_map(self); + if (build_row_cast_map(self) != 0) { + PyErr_SetString(OperationalError, "Error while building row_cast_map"); + goto error; + } rc = _sqlite_step_with_busyhandler(self->statement->st, self->connection); if (rc != SQLITE_DONE && rc != SQLITE_ROW) { @@ -543,8 +605,14 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args) if (self->description == Py_None) { Py_DECREF(self->description); self->description = PyTuple_New(numcols); + if (!self->description) { + goto error; + } for (i = 0; i < numcols; i++) { descriptor = PyTuple_New(7); + if (!descriptor) { + goto error; + } PyTuple_SetItem(descriptor, 0, _build_column_name(sqlite3_column_name(self->statement->st, i))); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); @@ -608,8 +676,8 @@ error: if (PyErr_Occurred()) { return NULL; } else { - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(self); + return (PyObject*)self; } } @@ -658,6 +726,9 @@ PyObject* cursor_executescript(Cursor* self, PyObject* args) /* commit first */ func_args = PyTuple_New(0); + if (!func_args) { + goto error; + } result = connection_commit(self->connection, func_args); Py_DECREF(func_args); if (!result) { @@ -710,8 +781,8 @@ error: if (PyErr_Occurred()) { return NULL; } else { - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(self); + return (PyObject*)self; } } @@ -789,9 +860,12 @@ PyObject* cursor_fetchmany(Cursor* self, PyObject* args) } list = PyList_New(0); + if (!list) { + return NULL; + } /* just make sure we enter the loop */ - row = (PyObject*)1; + row = Py_None; while (row) { row = cursor_iternext(self); @@ -821,9 +895,12 @@ PyObject* cursor_fetchall(Cursor* self, PyObject* args) PyObject* list; list = PyList_New(0); + if (!list) { + return NULL; + } /* just make sure we enter the loop */ - row = (PyObject*)1; + row = (PyObject*)Py_None; while (row) { row = cursor_iternext(self); |