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.