Fix bug 246 (occasional buffer overflow related to varargs in assertion-failure strin...
authorMorgan Deters <mdeters@gmail.com>
Thu, 10 Mar 2011 21:05:13 +0000 (21:05 +0000)
committerMorgan Deters <mdeters@gmail.com>
Thu, 10 Mar 2011 21:05:13 +0000 (21:05 +0000)
src/util/Assert.cpp
test/unit/util/assert_white.h

index 84f970e87aa7806491bdbcf65f16d416071bc96f..ea0b26248768a1dad8304ab64989e57edaf30ee4 100644 (file)
@@ -54,7 +54,7 @@ void AssertionException::construct(const char* header, const char* extra,
     if(size < n) {
       va_list args_copy;
       va_copy(args_copy, args);
-      size += vsnprintf(buf + size, n - size, fmt, args);
+      size += vsnprintf(buf + size, n - size, fmt, args_copy);
       va_end(args_copy);
 
       if(size < n) {
index 389f2aa1b49c5530705e49c258239e8d5ec8fdcf..75006ed12698fdb95a9751f15a6bfe80a288ce7e 100644 (file)
@@ -71,6 +71,31 @@ public:
     } catch(...) {
       TS_FAIL("Threw the wrong kind of exception !");
     }
+
+    // Now test an assert with a format that drives it over the 512
+    // byte initial buffer.  This was a bug in r1441, see bug 246:
+    // http://goedel.cims.nyu.edu/bugzilla3/show_bug.cgi?id=246
+    string fmt = string(200, 'x') + " %s " + string(200, 'x');
+    string arg(200, 'y');
+    try {
+      AlwaysAssert(false, fmt.c_str(), arg.c_str());
+      TS_FAIL("Should have thrown an exception !");
+    } catch(AssertionException& e) {
+      // we don't want to match on the entire string, because it may
+      // have an absolute path to the unit test binary, line number
+      // info, etc.
+      const char* theString = e.toString().c_str();
+      const char* firstPart =
+        "Assertion failure\nvoid AssertWhite::testReallyLongAssert()\n";
+      string lastPartStr = "\n\n  false\n" + string(200, 'x') + " " +
+        string(200, 'y') + " " + string(200, 'x');
+      const char* lastPart = lastPartStr.c_str();
+      TS_ASSERT(strncmp(theString, firstPart, strlen(firstPart)) == 0);
+      TS_ASSERT(strncmp(theString + strlen(theString) - strlen(lastPart),
+                        lastPart, strlen(lastPart)) == 0);
+    } catch(...) {
+      TS_FAIL("Threw the wrong kind of exception !");
+    }
   }
 
   void testUnreachable() {