1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include "base/pickle.h" 8 #include "base/string_util.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPBody.h" 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h" 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" 13 #include "webkit/glue/glue_serialize.h" 14 #include "webkit/glue/web_io_operators.h" 15 16 using WebKit::WebData; 17 using WebKit::WebHistoryItem; 18 using WebKit::WebHTTPBody; 19 using WebKit::WebPoint; 20 using WebKit::WebString; 21 using WebKit::WebUChar; 22 using WebKit::WebVector; 23 24 namespace { 25 class GlueSerializeTest : public testing::Test { 26 public: 27 // Makes a FormData with some random data. 28 WebHTTPBody MakeFormData() { 29 WebHTTPBody http_body; 30 http_body.initialize(); 31 32 const char d1[] = "first data block"; 33 http_body.appendData(WebData(d1, sizeof(d1)-1)); 34 35 http_body.appendFile(WebString::fromUTF8("file.txt")); 36 37 const char d2[] = "data the second"; 38 http_body.appendData(WebData(d2, sizeof(d2)-1)); 39 40 return http_body; 41 } 42 43 // Constructs a HistoryItem with some random data and an optional child. 44 WebHistoryItem MakeHistoryItem(bool with_form_data, bool pregnant) { 45 WebHistoryItem item; 46 item.initialize(); 47 48 item.setURLString(WebString::fromUTF8("urlString")); 49 item.setOriginalURLString(WebString::fromUTF8("originalURLString")); 50 item.setTarget(WebString::fromUTF8("target")); 51 item.setParent(WebString::fromUTF8("parent")); 52 item.setTitle(WebString::fromUTF8("title")); 53 item.setAlternateTitle(WebString::fromUTF8("alternateTitle")); 54 item.setLastVisitedTime(13.37); 55 item.setScrollOffset(WebPoint(42, -42)); 56 item.setIsTargetItem(true); 57 item.setVisitCount(42*42); 58 59 WebVector<WebString> document_state(size_t(3)); 60 document_state[0] = WebString::fromUTF8("state1"); 61 document_state[1] = WebString::fromUTF8("state2"); 62 document_state[2] = WebString::fromUTF8("state AWESOME"); 63 item.setDocumentState(document_state); 64 65 // Form Data 66 if (with_form_data) { 67 item.setHTTPBody(MakeFormData()); 68 item.setHTTPContentType(WebString::fromUTF8("formContentType")); 69 } 70 71 // Setting the FormInfo causes the referrer to be set, so we set the 72 // referrer after setting the form info. 73 item.setReferrer(WebString::fromUTF8("referrer")); 74 75 // Children 76 if (pregnant) 77 item.appendToChildren(MakeHistoryItem(false, false)); 78 79 return item; 80 } 81 82 // Checks that a == b. 83 void HistoryItemExpectEqual(const WebHistoryItem& a, 84 const WebHistoryItem& b) { 85 EXPECT_EQ(string16(a.urlString()), string16(b.urlString())); 86 EXPECT_EQ(string16(a.originalURLString()), string16(b.originalURLString())); 87 EXPECT_EQ(string16(a.target()), string16(b.target())); 88 EXPECT_EQ(string16(a.parent()), string16(b.parent())); 89 EXPECT_EQ(string16(a.title()), string16(b.title())); 90 EXPECT_EQ(string16(a.alternateTitle()), string16(b.alternateTitle())); 91 EXPECT_EQ(a.lastVisitedTime(), b.lastVisitedTime()); 92 EXPECT_EQ(a.scrollOffset(), b.scrollOffset()); 93 EXPECT_EQ(a.isTargetItem(), b.isTargetItem()); 94 EXPECT_EQ(a.visitCount(), b.visitCount()); 95 EXPECT_EQ(string16(a.referrer()), string16(b.referrer())); 96 97 const WebVector<WebString>& a_docstate = a.documentState(); 98 const WebVector<WebString>& b_docstate = b.documentState(); 99 EXPECT_EQ(a_docstate.size(), b_docstate.size()); 100 for (size_t i = 0, c = a_docstate.size(); i < c; ++i) 101 EXPECT_EQ(string16(a_docstate[i]), string16(b_docstate[i])); 102 103 // Form Data 104 const WebHTTPBody& a_body = a.httpBody(); 105 const WebHTTPBody& b_body = b.httpBody(); 106 EXPECT_EQ(!a_body.isNull(), !b_body.isNull()); 107 if (!a_body.isNull() && !b_body.isNull()) { 108 EXPECT_EQ(a_body.elementCount(), b_body.elementCount()); 109 WebHTTPBody::Element a_elem, b_elem; 110 for (size_t i = 0; a_body.elementAt(i, a_elem) && 111 b_body.elementAt(i, b_elem); ++i) { 112 EXPECT_EQ(a_elem.type, b_elem.type); 113 if (a_elem.type == WebHTTPBody::Element::TypeData) { 114 EXPECT_EQ(std::string(a_elem.data.data(), a_elem.data.size()), 115 std::string(b_elem.data.data(), b_elem.data.size())); 116 } else { 117 EXPECT_EQ(string16(a_elem.filePath), string16(b_elem.filePath)); 118 } 119 } 120 } 121 EXPECT_EQ(string16(a.httpContentType()), string16(b.httpContentType())); 122 123 // Children 124 const WebVector<WebHistoryItem>& a_children = a.children(); 125 const WebVector<WebHistoryItem>& b_children = b.children(); 126 EXPECT_EQ(a_children.size(), b_children.size()); 127 for (size_t i = 0, c = a_children.size(); i < c; ++i) 128 HistoryItemExpectEqual(a_children[i], b_children[i]); 129 } 130 }; 131 132 // Test old versions of serialized data to ensure that newer versions of code 133 // can still read history items written by previous versions. 134 TEST_F(GlueSerializeTest, BackwardsCompatibleTest) { 135 const WebHistoryItem& item = MakeHistoryItem(false, false); 136 137 // Make sure version 3 (current version) can read versions 1 and 2. 138 for (int i = 1; i <= 2; i++) { 139 std::string serialized_item; 140 webkit_glue::HistoryItemToVersionedString(item, i, &serialized_item); 141 const WebHistoryItem& deserialized_item = 142 webkit_glue::HistoryItemFromString(serialized_item); 143 ASSERT_FALSE(item.isNull()); 144 ASSERT_FALSE(deserialized_item.isNull()); 145 HistoryItemExpectEqual(item, deserialized_item); 146 } 147 } 148 149 // Makes sure that a HistoryItem remains intact after being serialized and 150 // deserialized. 151 TEST_F(GlueSerializeTest, HistoryItemSerializeTest) { 152 const WebHistoryItem& item = MakeHistoryItem(true, true); 153 const std::string& serialized_item = webkit_glue::HistoryItemToString(item); 154 const WebHistoryItem& deserialized_item = 155 webkit_glue::HistoryItemFromString(serialized_item); 156 157 ASSERT_FALSE(item.isNull()); 158 ASSERT_FALSE(deserialized_item.isNull()); 159 HistoryItemExpectEqual(item, deserialized_item); 160 } 161 162 // Checks that broken messages don't take out our process. 163 TEST_F(GlueSerializeTest, BadMessagesTest) { 164 { 165 Pickle p; 166 // Version 1 167 p.WriteInt(1); 168 // Empty strings. 169 for (int i = 0; i < 6; ++i) 170 p.WriteInt(-1); 171 // Bad real number. 172 p.WriteInt(-1); 173 std::string s(static_cast<const char*>(p.data()), p.size()); 174 webkit_glue::HistoryItemFromString(s); 175 } 176 { 177 double d = 0; 178 Pickle p; 179 // Version 1 180 p.WriteInt(1); 181 // Empty strings. 182 for (int i = 0; i < 6; ++i) 183 p.WriteInt(-1); 184 // More misc fields. 185 p.WriteData(reinterpret_cast<const char*>(&d), sizeof(d)); 186 p.WriteInt(1); 187 p.WriteInt(1); 188 p.WriteInt(0); 189 p.WriteInt(0); 190 p.WriteInt(-1); 191 p.WriteInt(0); 192 // WebForm 193 p.WriteInt(1); 194 p.WriteInt(WebHTTPBody::Element::TypeData); 195 std::string s(static_cast<const char*>(p.data()), p.size()); 196 webkit_glue::HistoryItemFromString(s); 197 } 198 } 199 200 } // namespace 201