Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: google_apis/gcm/engine/connection_handler_impl_unittest.cc

Issue 643133003: [GCM] Fix crash when size packet splits two socket reads (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tests/corner cases Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "google_apis/gcm/engine/connection_handler_impl.h" 5 #include "google_apis/gcm/engine/connection_handler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 129
130 private: 130 private:
131 void ReadContinuation(ScopedMessage* dst_proto, ScopedMessage new_proto); 131 void ReadContinuation(ScopedMessage* dst_proto, ScopedMessage new_proto);
132 void WriteContinuation(); 132 void WriteContinuation();
133 void ConnectionContinuation(int error); 133 void ConnectionContinuation(int error);
134 134
135 // SocketStreams and their data provider. 135 // SocketStreams and their data provider.
136 ReadList mock_reads_; 136 ReadList mock_reads_;
137 WriteList mock_writes_; 137 WriteList mock_writes_;
138 scoped_ptr<net::DelayedSocketData> data_provider_; 138 scoped_ptr<net::DelayedSocketData> data_provider_;
139 scoped_ptr<SocketInputStream> socket_input_stream_;
140 scoped_ptr<SocketOutputStream> socket_output_stream_;
141 139
142 // The connection handler being tested. 140 // The connection handler being tested.
143 scoped_ptr<ConnectionHandlerImpl> connection_handler_; 141 scoped_ptr<ConnectionHandlerImpl> connection_handler_;
144 142
145 // The last connection error received. 143 // The last connection error received.
146 int last_error_; 144 int last_error_;
147 145
148 // net:: components. 146 // net:: components.
149 scoped_ptr<net::StreamSocket> socket_; 147 scoped_ptr<net::StreamSocket> socket_;
150 net::MockClientSocketFactory socket_factory_; 148 net::MockClientSocketFactory socket_factory_;
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 data_message.set_from(kDataMsgFrom); 665 data_message.set_from(kDataMsgFrom);
668 data_message.set_category(kDataMsgCategory); 666 data_message.set_category(kDataMsgCategory);
669 connection_handler()->SendMessage(data_message); 667 connection_handler()->SendMessage(data_message);
670 EXPECT_FALSE(connection_handler()->CanSendMessage()); 668 EXPECT_FALSE(connection_handler()->CanSendMessage());
671 WaitForMessage(); // The message send. Should result in an error 669 WaitForMessage(); // The message send. Should result in an error
672 EXPECT_FALSE(connection_handler()->CanSendMessage()); 670 EXPECT_FALSE(connection_handler()->CanSendMessage());
673 EXPECT_EQ(net::ERR_CONNECTION_CLOSED, last_error()); 671 EXPECT_EQ(net::ERR_CONNECTION_CLOSED, last_error());
674 } 672 }
675 673
676 // Receive a message whose size field was corrupted and is larger than the 674 // Receive a message whose size field was corrupted and is larger than the
677 // socket's buffer. Should fail gracefully. 675 // socket's buffer. Should fail gracefully with a size error.
678 TEST_F(GCMConnectionHandlerImplTest, CorruptedSize) { 676 TEST_F(GCMConnectionHandlerImplTest, OutOfBuffer) {
679 std::string handshake_request = EncodeHandshakeRequest(); 677 std::string handshake_request = EncodeHandshakeRequest();
680 WriteList write_list(1, net::MockWrite(net::ASYNC, 678 WriteList write_list(1, net::MockWrite(net::ASYNC,
681 handshake_request.c_str(), 679 handshake_request.c_str(),
682 handshake_request.size())); 680 handshake_request.size()));
683 std::string handshake_response = EncodeHandshakeResponse(); 681 std::string handshake_response = EncodeHandshakeResponse();
684 682
685 // Fill a string with 9000 character zero. 683 // Fill a string with 9000 character zero.
686 std::string data_message_proto(9000, '0'); 684 std::string data_message_proto(9000, '0');
687 std::string data_message_pkt = 685 std::string data_message_pkt =
688 EncodePacket(kDataMessageStanzaTag, data_message_proto); 686 EncodePacket(kDataMessageStanzaTag, data_message_proto);
689 ReadList read_list; 687 ReadList read_list;
690 read_list.push_back(net::MockRead(net::ASYNC, 688 read_list.push_back(net::MockRead(net::ASYNC,
691 handshake_response.c_str(), 689 handshake_response.c_str(),
692 handshake_response.size())); 690 handshake_response.size()));
693 read_list.push_back(net::MockRead(net::ASYNC, 691 read_list.push_back(net::MockRead(net::ASYNC,
694 data_message_pkt.c_str(), 692 data_message_pkt.c_str(),
695 data_message_pkt.size())); 693 data_message_pkt.size()));
696 BuildSocket(read_list, write_list); 694 BuildSocket(read_list, write_list);
697 695
698 ScopedMessage received_message; 696 ScopedMessage received_message;
699 Connect(&received_message); 697 Connect(&received_message);
700 WaitForMessage(); // The login send. 698 WaitForMessage(); // The login send.
701 WaitForMessage(); // The login response. 699 WaitForMessage(); // The login response.
702 received_message.reset(); 700 received_message.reset();
703 WaitForMessage(); // The data message. 701 WaitForMessage(); // The data message.
704 EXPECT_FALSE(received_message.get()); 702 EXPECT_FALSE(received_message.get());
705 EXPECT_EQ(net::ERR_FILE_TOO_BIG, last_error()); 703 EXPECT_EQ(net::ERR_FILE_TOO_BIG, last_error());
706 } 704 }
707 705
706 // Receive a message whose size field was corrupted and takes more than two
707 // bytes to encode. Should fail gracefully with a size error.
708 TEST_F(GCMConnectionHandlerImplTest, InvalidSizePacket) {
709 std::string handshake_request = EncodeHandshakeRequest();
710 WriteList write_list(1, net::MockWrite(net::ASYNC,
711 handshake_request.c_str(),
712 handshake_request.size()));
713 std::string handshake_response = EncodeHandshakeResponse();
714
715 // Fill a string with 20000 character zero (which uses more than 2 bytes to
716 // encode the size packet).
717 std::string data_message_proto(20000, '0');
718 std::string data_message_pkt =
719 EncodePacket(kDataMessageStanzaTag, data_message_proto);
720 ReadList read_list;
721 read_list.push_back(net::MockRead(net::ASYNC,
722 handshake_response.c_str(),
723 handshake_response.size()));
724 read_list.push_back(net::MockRead(net::ASYNC,
725 data_message_pkt.c_str(),
726 data_message_pkt.size()));
727 BuildSocket(read_list, write_list);
728
729 ScopedMessage received_message;
730 Connect(&received_message);
731 WaitForMessage(); // The login send.
732 WaitForMessage(); // The login response.
733 received_message.reset();
734 WaitForMessage(); // The data message.
735 EXPECT_FALSE(received_message.get());
736 EXPECT_EQ(net::ERR_FILE_TOO_BIG, last_error());
737 }
738
739 // Make sure a message with an invalid tag is handled gracefully and resets
740 // the connection with an invalid argument error.
741 TEST_F(GCMConnectionHandlerImplTest, InvalidTag) {
742 std::string handshake_request = EncodeHandshakeRequest();
743 WriteList write_list(1, net::MockWrite(net::ASYNC,
744 handshake_request.c_str(),
745 handshake_request.size()));
746 std::string handshake_response = EncodeHandshakeResponse();
747
748 std::string invalid_message = "0";
749 std::string invalid_message_pkt =
750 EncodePacket(100, invalid_message);
fgorski 2014/10/20 22:11:55 nit: could you name that value? could be a const i
Nicolas Zea 2014/10/21 00:02:54 Done.
751 ReadList read_list;
752 read_list.push_back(net::MockRead(net::ASYNC,
753 handshake_response.c_str(),
754 handshake_response.size()));
755 read_list.push_back(net::MockRead(net::ASYNC,
756 invalid_message_pkt.c_str(),
757 invalid_message_pkt.size()));
758 BuildSocket(read_list, write_list);
759
760 ScopedMessage received_message;
761 Connect(&received_message);
762 WaitForMessage(); // The login send.
763 WaitForMessage(); // The login response.
764 received_message.reset();
765 WaitForMessage(); // The invalid message.
766 EXPECT_FALSE(received_message.get());
767 EXPECT_EQ(net::ERR_INVALID_ARGUMENT, last_error());
768 }
769
770 // Receive a message where the size field spans two socket reads.
fgorski 2014/10/20 22:11:55 nit: pleas call out that it is byte 2 and 3 explic
Nicolas Zea 2014/10/21 00:02:54 Done.
771 TEST_F(GCMConnectionHandlerImplTest, RecvMsgSplitSize) {
772 std::string handshake_request = EncodeHandshakeRequest();
773 WriteList write_list(1, net::MockWrite(net::ASYNC,
774 handshake_request.c_str(),
775 handshake_request.size()));
776 std::string handshake_response = EncodeHandshakeResponse();
777
778 std::string data_message_proto =
779 BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
780 std::string data_message_pkt =
781 EncodePacket(kDataMessageStanzaTag, data_message_proto);
782 DCHECK_GT(data_message_pkt.size(), 128U);
783 ReadList read_list;
784 read_list.push_back(net::MockRead(net::ASYNC,
785 handshake_response.c_str(),
786 handshake_response.size()));
787 read_list.push_back(net::MockRead(net::ASYNC,
788 data_message_pkt.c_str(),
789 2));
790 read_list.push_back(net::MockRead(net::ASYNC,
791 data_message_pkt.c_str() + 2,
792 data_message_pkt.size() - 2));
793 BuildSocket(read_list, write_list);
794
795 ScopedMessage received_message;
796 Connect(&received_message);
797 WaitForMessage(); // The login send.
798 WaitForMessage(); // The login response.
799 WaitForMessage(); // The data message.
800 ASSERT_TRUE(received_message.get());
801 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
802 EXPECT_EQ(net::OK, last_error());
803 }
804
708 } // namespace 805 } // namespace
709 } // namespace gcm 806 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698