Fix a use-after-free when sending queued messages is aborted for blocked channel.

BUG=4187
R=pthatcher@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/39519004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@8119 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/datachannel.cc b/talk/app/webrtc/datachannel.cc
index f9765aa..05c934c 100644
--- a/talk/app/webrtc/datachannel.cc
+++ b/talk/app/webrtc/datachannel.cc
@@ -463,11 +463,13 @@
   ASSERT(was_ever_writable_ && state_ == kOpen);
 
   while (!queued_send_data_.Empty()) {
-    rtc::scoped_ptr<DataBuffer> buffer(queued_send_data_.Front());
+    DataBuffer* buffer = queued_send_data_.Front();
     if (!SendDataMessage(*buffer, false)) {
+      // Leave the message in the queue if sending is aborted.
       break;
     }
     queued_send_data_.Pop();
+    delete buffer;
   }
 }
 
diff --git a/talk/app/webrtc/datachannel_unittest.cc b/talk/app/webrtc/datachannel_unittest.cc
index 30bb576..6a73fbc 100644
--- a/talk/app/webrtc/datachannel_unittest.cc
+++ b/talk/app/webrtc/datachannel_unittest.cc
@@ -162,6 +162,24 @@
   EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
 }
 
+// Tests that no crash when the channel is blocked right away while trying to
+// send queued data.
+TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) {
+  SetChannelReady();
+  webrtc::DataBuffer buffer("abcd");
+  provider_.set_send_blocked(true);
+  EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
+
+  // Set channel ready while it is still blocked.
+  SetChannelReady();
+  EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount());
+
+  // Unblock the channel to send queued data again, there should be no crash.
+  provider_.set_send_blocked(false);
+  SetChannelReady();
+  EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
+}
+
 // Tests that the queued control message is sent when channel is ready.
 TEST_F(SctpDataChannelTest, OpenMessageSent) {
   // Initially the id is unassigned.