[Python-checkins] r50783 - python/trunk/Modules/_bsddb.c

neal.norwitz python-checkins at python.org
Sun Jul 23 10:01:43 CEST 2006


Author: neal.norwitz
Date: Sun Jul 23 10:01:43 2006
New Revision: 50783

Modified:
   python/trunk/Modules/_bsddb.c
Log:
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.


Modified: python/trunk/Modules/_bsddb.c
==============================================================================
--- python/trunk/Modules/_bsddb.c	(original)
+++ python/trunk/Modules/_bsddb.c	Sun Jul 23 10:01:43 2006
@@ -528,6 +528,7 @@
     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 @@
 #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 @@
     }
 
     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 @@
 
     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


More information about the Python-checkins mailing list