THRIFT-926. cpp: TMemoryBuffer: Uphold the strong exception safety guarantee

Previously, if we had a realloc failure when growing a TMemoryBuffer, we
would leave the buffer in an invalid state (bufferSize_ would reflect
the desired size, rather than the actual size).  Now, we make no change
to any member variables if realloc fails.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005165 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TBufferTransports.cpp b/lib/cpp/src/transport/TBufferTransports.cpp
index 6ba70e2..45913f4 100644
--- a/lib/cpp/src/transport/TBufferTransports.cpp
+++ b/lib/cpp/src/transport/TBufferTransports.cpp
@@ -324,24 +324,25 @@
   }
 
   // Grow the buffer as necessary.
+  uint32_t new_size = bufferSize_;
   while (len > avail) {
-    bufferSize_ *= 2;
-    wBound_ = buffer_ + bufferSize_;
-    avail = available_write();
+    new_size = new_size > 0 ? new_size * 2 : 1;
+    avail = available_write() + (new_size - bufferSize_);
   }
 
   // Allocate into a new pointer so we don't bork ours if it fails.
-  void* new_buffer = std::realloc(buffer_, bufferSize_);
+  void* new_buffer = std::realloc(buffer_, new_size);
   if (new_buffer == NULL) {
     throw TTransportException("Out of memory.");
   }
+  bufferSize_ = new_size;
 
   ptrdiff_t offset = (uint8_t*)new_buffer - buffer_;
   buffer_ += offset;
   rBase_ += offset;
   rBound_ += offset;
   wBase_ += offset;
-  wBound_ += offset;
+  wBound_ = buffer_ + bufferSize_;
 }
 
 void TMemoryBuffer::writeSlow(const uint8_t* buf, uint32_t len) {