summaryrefslogtreecommitdiffstats
path: root/remoting/signaling
diff options
context:
space:
mode:
authorsergeyu <sergeyu@chromium.org>2015-06-10 19:23:35 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-11 02:24:10 +0000
commit56988978ff675e340927da78f65c123f8b6a0008 (patch)
tree673f3bb6d8919c55c0bab104363ded2e0f5b2dc8 /remoting/signaling
parent8314b5f3b3da64d28039ecea71b48db7ce028ed3 (diff)
downloadchromium_src-56988978ff675e340927da78f65c123f8b6a0008.zip
chromium_src-56988978ff675e340927da78f65c123f8b6a0008.tar.gz
chromium_src-56988978ff675e340927da78f65c123f8b6a0008.tar.bz2
Fix XmppLoginHandler to handle destruction from delegate methods.
XmppLoginHandler was crashing when it's destroyed from SendMessage(). E.g. it can happen when Write() fails after TLS handshake. Also added unittests to test this scenario. BUG=498989 Review URL: https://codereview.chromium.org/1179543004 Cr-Commit-Position: refs/heads/master@{#333877}
Diffstat (limited to 'remoting/signaling')
-rw-r--r--remoting/signaling/xmpp_login_handler.cc8
-rw-r--r--remoting/signaling/xmpp_login_handler.h1
-rw-r--r--remoting/signaling/xmpp_login_handler_unittest.cc41
3 files changed, 46 insertions, 4 deletions
diff --git a/remoting/signaling/xmpp_login_handler.cc b/remoting/signaling/xmpp_login_handler.cc
index cc3ae94..448ecbe 100644
--- a/remoting/signaling/xmpp_login_handler.cc
+++ b/remoting/signaling/xmpp_login_handler.cc
@@ -221,14 +221,14 @@ void XmppLoginHandler::OnParserError() {
}
void XmppLoginHandler::StartStream(const std::string& first_message) {
- delegate_->SendMessage("<stream:stream to=\"" + server_ +
- "\" version=\"1.0\" xmlns=\"jabber:client\" "
- "xmlns:stream=\"http://etherx.jabber.org/streams\">" +
- first_message);
stream_parser_.reset(new XmppStreamParser());
stream_parser_->SetCallbacks(
base::Bind(&XmppLoginHandler::OnStanza, base::Unretained(this)),
base::Bind(&XmppLoginHandler::OnParserError, base::Unretained(this)));
+ delegate_->SendMessage("<stream:stream to=\"" + server_ +
+ "\" version=\"1.0\" xmlns=\"jabber:client\" "
+ "xmlns:stream=\"http://etherx.jabber.org/streams\">" +
+ first_message);
}
void XmppLoginHandler::OnError(SignalStrategy::Error error) {
diff --git a/remoting/signaling/xmpp_login_handler.h b/remoting/signaling/xmpp_login_handler.h
index 10af045..61f978a 100644
--- a/remoting/signaling/xmpp_login_handler.h
+++ b/remoting/signaling/xmpp_login_handler.h
@@ -35,6 +35,7 @@ class XmppLoginHandler {
public:
Delegate() {}
+ // All Delegate methods are allowed to destroy XmppLoginHandler.
virtual void SendMessage(const std::string& message) = 0;
virtual void StartTls() = 0;
virtual void OnHandshakeDone(const std::string& jid,
diff --git a/remoting/signaling/xmpp_login_handler_unittest.cc b/remoting/signaling/xmpp_login_handler_unittest.cc
index 59afdb8..ab9abe0 100644
--- a/remoting/signaling/xmpp_login_handler_unittest.cc
+++ b/remoting/signaling/xmpp_login_handler_unittest.cc
@@ -38,21 +38,29 @@ class XmppLoginHandlerTest : public testing::Test,
void SendMessage(const std::string& message) override {
sent_data_ += message;
+ if (delete_login_handler_from_delegate_)
+ login_handler_.reset();
}
void StartTls() override {
start_tls_called_ = true;
+ if (delete_login_handler_from_delegate_)
+ login_handler_.reset();
}
void OnHandshakeDone(const std::string& jid,
scoped_ptr<XmppStreamParser> parser) override {
jid_ = jid;
parser_ = parser.Pass();
+ if (delete_login_handler_from_delegate_)
+ login_handler_.reset();
}
void OnLoginHandlerError(SignalStrategy::Error error) override {
EXPECT_NE(error, SignalStrategy::OK);
error_ = error;
+ if (delete_login_handler_from_delegate_)
+ login_handler_.reset();
}
protected:
@@ -66,6 +74,7 @@ class XmppLoginHandlerTest : public testing::Test,
std::string jid_;
scoped_ptr<XmppStreamParser> parser_;
SignalStrategy::Error error_;
+ bool delete_login_handler_from_delegate_ = false;
};
void XmppLoginHandlerTest::HandshakeBase() {
@@ -127,6 +136,10 @@ TEST_F(XmppLoginHandlerTest, SuccessfulAuth) {
"</iq>");
sent_data_.clear();
+ // |login_handler_| will call OnHandshakeDone() which will delete
+ // |login_handler_|.
+ delete_login_handler_from_delegate_ = true;
+
login_handler_->OnDataReceived(
"<stream:stream from=\"google.com\" id=\"104FA10576E2AA80\" "
"version=\"1.0\" "
@@ -145,6 +158,7 @@ TEST_F(XmppLoginHandlerTest, SuccessfulAuth) {
EXPECT_EQ(jid_, std::string(kTestUsername) + "/chromoting52B4920E");
EXPECT_TRUE(parser_);
+ EXPECT_FALSE(login_handler_);
}
TEST_F(XmppLoginHandlerTest, StartTlsHandshake) {
@@ -216,8 +230,35 @@ TEST_F(XmppLoginHandlerTest, NoTls) {
TEST_F(XmppLoginHandlerTest, StreamParseError) {
HandshakeBase();
+ delete_login_handler_from_delegate_ = true;
login_handler_->OnDataReceived("BAD DATA");
EXPECT_EQ(error_, SignalStrategy::PROTOCOL_ERROR);
}
+// Verify that LoginHandler doesn't crash when destroyed from
+// Delegate::SendMessage().
+TEST_F(XmppLoginHandlerTest, DeleteInSendMessage) {
+ login_handler_.reset(
+ new XmppLoginHandler("google.com", kTestUsername, kTestToken,
+ XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE, this));
+ login_handler_->Start();
+ EXPECT_TRUE(start_tls_called_);
+
+ delete_login_handler_from_delegate_ = true;
+ login_handler_->OnTlsStarted();
+ EXPECT_FALSE(login_handler_);
+}
+
+// Verify that LoginHandler doesn't crash when destroyed from
+// Delegate::StartTls().
+TEST_F(XmppLoginHandlerTest, DeleteInStartTls) {
+ login_handler_.reset(
+ new XmppLoginHandler("google.com", kTestUsername, kTestToken,
+ XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE, this));
+ delete_login_handler_from_delegate_ = true;
+ login_handler_->Start();
+ EXPECT_TRUE(start_tls_called_);
+ EXPECT_FALSE(login_handler_);
+}
+
} // namespace remoting