Ensure we don't write beyond errText. I think I got this right, but
it definitely could use some review to ensure I'm not off by one and there's no possible overflow/wrap-around of bytes_left. Reported by Klocwork #1. Fix a problem if there is a failure allocating self->db. Found with failmalloc.
This commit is contained in:
parent
9029b5f289
commit
dce937f32c
|
@ -528,6 +528,7 @@ static int makeDBError(int err)
|
|||
PyObject *errObj = NULL;
|
||||
PyObject *errTuple = NULL;
|
||||
int exceptionRaised = 0;
|
||||
unsigned int bytes_left;
|
||||
|
||||
switch (err) {
|
||||
case 0: /* successful, no error */ break;
|
||||
|
@ -535,12 +536,15 @@ static int makeDBError(int err)
|
|||
#if (DBVER < 41)
|
||||
case DB_INCOMPLETE:
|
||||
#if INCOMPLETE_IS_WARNING
|
||||
our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
|
||||
if (_db_errmsg[0]) {
|
||||
bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
|
||||
/* Ensure that bytes_left never goes negative */
|
||||
if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
|
||||
bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
|
||||
assert(bytes_left >= 0);
|
||||
strcat(errTxt, " -- ");
|
||||
strcat(errTxt, _db_errmsg);
|
||||
_db_errmsg[0] = 0;
|
||||
strncat(errTxt, _db_errmsg, bytes_left);
|
||||
}
|
||||
_db_errmsg[0] = 0;
|
||||
#ifdef HAVE_WARNINGS
|
||||
exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
|
||||
#else
|
||||
|
@ -588,12 +592,15 @@ static int makeDBError(int err)
|
|||
}
|
||||
|
||||
if (errObj != NULL) {
|
||||
our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
|
||||
if (_db_errmsg[0]) {
|
||||
bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
|
||||
/* Ensure that bytes_left never goes negative */
|
||||
if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
|
||||
bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
|
||||
assert(bytes_left >= 0);
|
||||
strcat(errTxt, " -- ");
|
||||
strcat(errTxt, _db_errmsg);
|
||||
_db_errmsg[0] = 0;
|
||||
strncat(errTxt, _db_errmsg, bytes_left);
|
||||
}
|
||||
_db_errmsg[0] = 0;
|
||||
|
||||
errTuple = Py_BuildValue("(is)", err, errTxt);
|
||||
PyErr_SetObject(errObj, errTuple);
|
||||
|
@ -798,10 +805,12 @@ newDBObject(DBEnvObject* arg, int flags)
|
|||
|
||||
MYDB_BEGIN_ALLOW_THREADS;
|
||||
err = db_create(&self->db, db_env, flags);
|
||||
self->db->set_errcall(self->db, _db_errorCallback);
|
||||
if (self->db != NULL) {
|
||||
self->db->set_errcall(self->db, _db_errorCallback);
|
||||
#if (DBVER >= 33)
|
||||
self->db->app_private = (void*)self;
|
||||
self->db->app_private = (void*)self;
|
||||
#endif
|
||||
}
|
||||
MYDB_END_ALLOW_THREADS;
|
||||
/* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
|
||||
* list so that a DBEnv can refuse to close without aborting any open
|
||||
|
|
Loading…
Reference in New Issue