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

Side by Side Diff: third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp

Issue 2842653005: WebFrameSerializerSanitizationTest validates generated MHTML. (Closed)
Patch Set: Rebase. Created 3 years, 7 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "public/web/WebFrameSerializer.h" 31 #include "public/web/WebFrameSerializer.h"
32 32
33 #include "core/exported/WebViewBase.h" 33 #include "core/exported/WebViewBase.h"
34 #include "platform/mhtml/MHTMLArchive.h"
35 #include "platform/mhtml/MHTMLParser.h"
34 #include "platform/testing/HistogramTester.h" 36 #include "platform/testing/HistogramTester.h"
35 #include "platform/testing/URLTestHelpers.h" 37 #include "platform/testing/URLTestHelpers.h"
36 #include "platform/testing/UnitTestHelpers.h" 38 #include "platform/testing/UnitTestHelpers.h"
37 #include "platform/weborigin/KURL.h" 39 #include "platform/weborigin/KURL.h"
38 #include "platform/wtf/text/StringBuilder.h" 40 #include "platform/wtf/text/StringBuilder.h"
39 #include "public/platform/Platform.h" 41 #include "public/platform/Platform.h"
40 #include "public/platform/WebCString.h" 42 #include "public/platform/WebCString.h"
41 #include "public/platform/WebCache.h" 43 #include "public/platform/WebCache.h"
42 #include "public/platform/WebString.h" 44 #include "public/platform/WebString.h"
43 #include "public/platform/WebURL.h" 45 #include "public/platform/WebURL.h"
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 EXPECT_EQ("<!-- saved from url=(0030)http://www.test.com/?-%2Dx-%2D -->", 214 EXPECT_EQ("<!-- saved from url=(0030)http://www.test.com/?-%2Dx-%2D -->",
213 actual_html.Substring(1, 60)); 215 actual_html.Substring(1, 60));
214 } 216 }
215 217
216 class WebFrameSerializerSanitizationTest : public WebFrameSerializerTest { 218 class WebFrameSerializerSanitizationTest : public WebFrameSerializerTest {
217 protected: 219 protected:
218 WebFrameSerializerSanitizationTest() {} 220 WebFrameSerializerSanitizationTest() {}
219 221
220 ~WebFrameSerializerSanitizationTest() override {} 222 ~WebFrameSerializerSanitizationTest() override {}
221 223
222 String GenerateMHTMLParts(const String& url, 224 String GenerateMHTMLFromHtml(const String& url, const String& file_name) {
223 const String& file_name, 225 return GenerateMHTML(url, file_name, "text/html", false);
224 const String& mime_type = "text/html") { 226 }
227
228 String GenerateMHTMLPartsFromPng(const String& url, const String& file_name) {
229 return GenerateMHTML(url, file_name, "image/png", true);
230 }
231
232 String GenerateMHTML(const String& url,
233 const String& file_name,
234 const String& mime_type,
235 const bool only_body_parts) {
225 KURL parsed_url(kParsedURLString, url); 236 KURL parsed_url(kParsedURLString, url);
226 String file_path("frameserialization/" + file_name); 237 String file_path("frameserialization/" + file_name);
227 RegisterMockedFileURLLoad(parsed_url, file_path, mime_type); 238 RegisterMockedFileURLLoad(parsed_url, file_path, mime_type);
228 FrameTestHelpers::LoadFrame(MainFrameImpl(), url.Utf8().data()); 239 FrameTestHelpers::LoadFrame(MainFrameImpl(), url.Utf8().data());
229 WebThreadSafeData result = WebFrameSerializer::GenerateMHTMLParts( 240 // Boundaries are normally randomly generated but this one is predefined for
230 WebString("boundary"), MainFrameImpl(), &mhtml_delegate_); 241 // simplicity and as good as any other. Plus it gets used in almost all the
231 return String(result.Data(), result.size()); 242 // examples in the MHTML spec - RFC 2557.
243 const WebString boundary("boundary-example");
244 StringBuilder mhtml;
245 if (!only_body_parts) {
246 WebThreadSafeData header_result = WebFrameSerializer::GenerateMHTMLHeader(
247 boundary, MainFrameImpl(), &mhtml_delegate_);
248 mhtml.Append(header_result.Data(), header_result.size());
249 }
250
251 WebThreadSafeData body_result = WebFrameSerializer::GenerateMHTMLParts(
252 boundary, MainFrameImpl(), &mhtml_delegate_);
253 mhtml.Append(body_result.Data(), body_result.size());
254
255 if (!only_body_parts) {
256 RefPtr<RawData> footer_data = RawData::Create();
257 MHTMLArchive::GenerateMHTMLFooterForTesting(boundary,
258 *footer_data->MutableData());
259 mhtml.Append(footer_data->data(), footer_data->length());
260 }
261
262 String mhtml_string = mhtml.ToString();
263 if (!only_body_parts) {
264 // Validate the generated MHTML.
265 MHTMLParser parser(SharedBuffer::Create(mhtml_string.Characters8(),
266 size_t(mhtml_string.length())));
267 EXPECT_FALSE(parser.ParseArchive().IsEmpty())
268 << "Generated MHTML is not well formed";
269 }
270 return mhtml_string;
232 } 271 }
233 272
234 void SetRemovePopupOverlay(bool remove_popup_overlay) { 273 void SetRemovePopupOverlay(bool remove_popup_overlay) {
235 mhtml_delegate_.SetRemovePopupOverlay(remove_popup_overlay); 274 mhtml_delegate_.SetRemovePopupOverlay(remove_popup_overlay);
236 } 275 }
237 276
238 protected: 277 protected:
239 HistogramTester histogram_tester_; 278 HistogramTester histogram_tester_;
240 279
241 private: 280 private:
242 SimpleMHTMLPartsGenerationDelegate mhtml_delegate_; 281 SimpleMHTMLPartsGenerationDelegate mhtml_delegate_;
243 }; 282 };
244 283
245 TEST_F(WebFrameSerializerSanitizationTest, RemoveInlineScriptInAttributes) { 284 TEST_F(WebFrameSerializerSanitizationTest, RemoveInlineScriptInAttributes) {
246 String mhtml = 285 String mhtml =
247 GenerateMHTMLParts("http://www.test.com", "script_in_attributes.html"); 286 GenerateMHTMLFromHtml("http://www.test.com", "script_in_attributes.html");
248 287
249 // These scripting attributes should be removed. 288 // These scripting attributes should be removed.
250 EXPECT_EQ(WTF::kNotFound, mhtml.Find("onload=")); 289 EXPECT_EQ(WTF::kNotFound, mhtml.Find("onload="));
251 EXPECT_EQ(WTF::kNotFound, mhtml.Find("ONLOAD=")); 290 EXPECT_EQ(WTF::kNotFound, mhtml.Find("ONLOAD="));
252 EXPECT_EQ(WTF::kNotFound, mhtml.Find("onclick=")); 291 EXPECT_EQ(WTF::kNotFound, mhtml.Find("onclick="));
253 EXPECT_EQ(WTF::kNotFound, mhtml.Find("href=")); 292 EXPECT_EQ(WTF::kNotFound, mhtml.Find("href="));
254 EXPECT_EQ(WTF::kNotFound, mhtml.Find("from=")); 293 EXPECT_EQ(WTF::kNotFound, mhtml.Find("from="));
255 EXPECT_EQ(WTF::kNotFound, mhtml.Find("to=")); 294 EXPECT_EQ(WTF::kNotFound, mhtml.Find("to="));
256 EXPECT_EQ(WTF::kNotFound, mhtml.Find("javascript:")); 295 EXPECT_EQ(WTF::kNotFound, mhtml.Find("javascript:"));
257 296
258 // These non-scripting attributes should remain intact. 297 // These non-scripting attributes should remain intact.
259 EXPECT_NE(WTF::kNotFound, mhtml.Find("class=")); 298 EXPECT_NE(WTF::kNotFound, mhtml.Find("class="));
260 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=")); 299 EXPECT_NE(WTF::kNotFound, mhtml.Find("id="));
261 300
262 // srcdoc attribute of frame element should be replaced with src attribute. 301 // srcdoc attribute of frame element should be replaced with src attribute.
263 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcdoc=")); 302 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcdoc="));
264 EXPECT_NE(WTF::kNotFound, mhtml.Find("src=")); 303 EXPECT_NE(WTF::kNotFound, mhtml.Find("src="));
265 } 304 }
266 305
267 TEST_F(WebFrameSerializerSanitizationTest, DisableFormElements) { 306 TEST_F(WebFrameSerializerSanitizationTest, DisableFormElements) {
268 String mhtml = GenerateMHTMLParts("http://www.test.com", "form.html"); 307 String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "form.html");
269 308
270 const char kDisabledAttr[] = "disabled=3D\"\""; 309 const char kDisabledAttr[] = "disabled=3D\"\"";
271 int matches = 310 int matches =
272 MatchSubstring(mhtml, kDisabledAttr, arraysize(kDisabledAttr) - 1); 311 MatchSubstring(mhtml, kDisabledAttr, arraysize(kDisabledAttr) - 1);
273 EXPECT_EQ(21, matches); 312 EXPECT_EQ(21, matches);
274 } 313 }
275 314
276 TEST_F(WebFrameSerializerSanitizationTest, RemoveHiddenElements) { 315 TEST_F(WebFrameSerializerSanitizationTest, RemoveHiddenElements) {
277 String mhtml = 316 String mhtml =
278 GenerateMHTMLParts("http://www.test.com", "hidden_elements.html"); 317 GenerateMHTMLFromHtml("http://www.test.com", "hidden_elements.html");
279 318
280 // The element with hidden attribute should be removed. 319 // The element with hidden attribute should be removed.
281 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<p id=3D\"hidden_id\"")); 320 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<p id=3D\"hidden_id\""));
282 321
283 // The hidden form element should be removed. 322 // The hidden form element should be removed.
284 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<input type=3D\"hidden\"")); 323 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<input type=3D\"hidden\""));
285 324
286 // All other hidden elements should not be removed. 325 // All other hidden elements should not be removed.
287 EXPECT_NE(WTF::kNotFound, mhtml.Find("<html")); 326 EXPECT_NE(WTF::kNotFound, mhtml.Find("<html"));
288 EXPECT_NE(WTF::kNotFound, mhtml.Find("<head")); 327 EXPECT_NE(WTF::kNotFound, mhtml.Find("<head"));
(...skipping 13 matching lines...) Expand all
302 // These visible elements should remain intact. 341 // These visible elements should remain intact.
303 EXPECT_NE(WTF::kNotFound, mhtml.Find("<p id=3D\"visible_id\"")); 342 EXPECT_NE(WTF::kNotFound, mhtml.Find("<p id=3D\"visible_id\""));
304 EXPECT_NE(WTF::kNotFound, mhtml.Find("<form")); 343 EXPECT_NE(WTF::kNotFound, mhtml.Find("<form"));
305 EXPECT_NE(WTF::kNotFound, mhtml.Find("<input type=3D\"text\"")); 344 EXPECT_NE(WTF::kNotFound, mhtml.Find("<input type=3D\"text\""));
306 EXPECT_NE(WTF::kNotFound, mhtml.Find("<div")); 345 EXPECT_NE(WTF::kNotFound, mhtml.Find("<div"));
307 } 346 }
308 347
309 // Regression test for crbug.com/678893, where in some cases serializing an 348 // Regression test for crbug.com/678893, where in some cases serializing an
310 // image document could cause code to pick an element from an empty container. 349 // image document could cause code to pick an element from an empty container.
311 TEST_F(WebFrameSerializerSanitizationTest, FromBrokenImageDocument) { 350 TEST_F(WebFrameSerializerSanitizationTest, FromBrokenImageDocument) {
312 String mhtml = GenerateMHTMLParts("http://www.test.com", "broken-image.png", 351 // This test only cares that the result of the parts generation is empty so it
313 "image/png"); 352 // is simpler to not generate only that instead of the full MHTML.
353 String mhtml =
354 GenerateMHTMLPartsFromPng("http://www.test.com", "broken-image.png");
314 EXPECT_TRUE(mhtml.IsEmpty()); 355 EXPECT_TRUE(mhtml.IsEmpty());
315 } 356 }
316 357
317 TEST_F(WebFrameSerializerSanitizationTest, ImageLoadedFromSrcsetForHiDPI) { 358 TEST_F(WebFrameSerializerSanitizationTest, ImageLoadedFromSrcsetForHiDPI) {
318 RegisterMockedFileURLLoad( 359 RegisterMockedFileURLLoad(
319 KURL(kParsedURLString, "http://www.test.com/1x.png"), 360 KURL(kParsedURLString, "http://www.test.com/1x.png"),
320 "frameserialization/1x.png"); 361 "frameserialization/1x.png");
321 RegisterMockedFileURLLoad( 362 RegisterMockedFileURLLoad(
322 KURL(kParsedURLString, "http://www.test.com/2x.png"), 363 KURL(kParsedURLString, "http://www.test.com/2x.png"),
323 "frameserialization/2x.png"); 364 "frameserialization/2x.png");
324 365
325 // Set high DPR in order to load image from srcset, instead of src. 366 // Set high DPR in order to load image from srcset, instead of src.
326 WebView()->SetDeviceScaleFactor(2.0f); 367 WebView()->SetDeviceScaleFactor(2.0f);
327 368
328 String mhtml = GenerateMHTMLParts("http://www.test.com", "img_srcset.html"); 369 String mhtml =
370 GenerateMHTMLFromHtml("http://www.test.com", "img_srcset.html");
329 371
330 // srcset attribute should be skipped. 372 // srcset attribute should be skipped.
331 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcset=")); 373 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcset="));
332 374
333 // Width and height attributes should be set when none is present in <img>. 375 // Width and height attributes should be set when none is present in <img>.
334 EXPECT_NE(WTF::kNotFound, 376 EXPECT_NE(WTF::kNotFound,
335 mhtml.Find("id=3D\"i1\" width=3D\"6\" height=3D\"6\">")); 377 mhtml.Find("id=3D\"i1\" width=3D\"6\" height=3D\"6\">"));
336 378
337 // Height attribute should not be set if width attribute is already present in 379 // Height attribute should not be set if width attribute is already present in
338 // <img> 380 // <img>
339 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i2\" width=3D\"8\">")); 381 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i2\" width=3D\"8\">"));
340 } 382 }
341 383
342 TEST_F(WebFrameSerializerSanitizationTest, ImageLoadedFromSrcForNormalDPI) { 384 TEST_F(WebFrameSerializerSanitizationTest, ImageLoadedFromSrcForNormalDPI) {
343 RegisterMockedFileURLLoad( 385 RegisterMockedFileURLLoad(
344 KURL(kParsedURLString, "http://www.test.com/1x.png"), 386 KURL(kParsedURLString, "http://www.test.com/1x.png"),
345 "frameserialization/1x.png"); 387 "frameserialization/1x.png");
346 RegisterMockedFileURLLoad( 388 RegisterMockedFileURLLoad(
347 KURL(kParsedURLString, "http://www.test.com/2x.png"), 389 KURL(kParsedURLString, "http://www.test.com/2x.png"),
348 "frameserialization/2x.png"); 390 "frameserialization/2x.png");
349 391
350 String mhtml = GenerateMHTMLParts("http://www.test.com", "img_srcset.html"); 392 String mhtml =
393 GenerateMHTMLFromHtml("http://www.test.com", "img_srcset.html");
351 394
352 // srcset attribute should be skipped. 395 // srcset attribute should be skipped.
353 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcset=")); 396 EXPECT_EQ(WTF::kNotFound, mhtml.Find("srcset="));
354 397
355 // New width and height attributes should not be set. 398 // New width and height attributes should not be set.
356 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i1\">")); 399 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i1\">"));
357 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i2\" width=3D\"8\">")); 400 EXPECT_NE(WTF::kNotFound, mhtml.Find("id=3D\"i2\" width=3D\"8\">"));
358 } 401 }
359 402
360 TEST_F(WebFrameSerializerSanitizationTest, RemovePopupOverlayIfRequested) { 403 TEST_F(WebFrameSerializerSanitizationTest, RemovePopupOverlayIfRequested) {
361 WebView()->Resize(WebSize(500, 500)); 404 WebView()->Resize(WebSize(500, 500));
362 SetRemovePopupOverlay(true); 405 SetRemovePopupOverlay(true);
363 String mhtml = GenerateMHTMLParts("http://www.test.com", "popup.html"); 406 String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "popup.html");
364 EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"overlay")); 407 EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"overlay"));
365 EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"modal")); 408 EXPECT_EQ(WTF::kNotFound, mhtml.Find("class=3D\"modal"));
366 histogram_tester_.ExpectUniqueSample( 409 histogram_tester_.ExpectUniqueSample(
367 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", true, 1); 410 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", true, 1);
368 } 411 }
369 412
370 TEST_F(WebFrameSerializerSanitizationTest, PopupOverlayNotFound) { 413 TEST_F(WebFrameSerializerSanitizationTest, PopupOverlayNotFound) {
371 WebView()->Resize(WebSize(500, 500)); 414 WebView()->Resize(WebSize(500, 500));
372 SetRemovePopupOverlay(true); 415 SetRemovePopupOverlay(true);
373 String mhtml = 416 String mhtml =
374 GenerateMHTMLParts("http://www.test.com", "text_only_page.html"); 417 GenerateMHTMLFromHtml("http://www.test.com", "text_only_page.html");
375 histogram_tester_.ExpectUniqueSample( 418 histogram_tester_.ExpectUniqueSample(
376 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", false, 1); 419 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", false, 1);
377 } 420 }
378 421
379 TEST_F(WebFrameSerializerSanitizationTest, KeepPopupOverlayIfNotRequested) { 422 TEST_F(WebFrameSerializerSanitizationTest, KeepPopupOverlayIfNotRequested) {
380 WebView()->Resize(WebSize(500, 500)); 423 WebView()->Resize(WebSize(500, 500));
381 SetRemovePopupOverlay(false); 424 SetRemovePopupOverlay(false);
382 String mhtml = GenerateMHTMLParts("http://www.test.com", "popup.html"); 425 String mhtml = GenerateMHTMLFromHtml("http://www.test.com", "popup.html");
383 EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"overlay")); 426 EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"overlay"));
384 EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"modal")); 427 EXPECT_NE(WTF::kNotFound, mhtml.Find("class=3D\"modal"));
385 histogram_tester_.ExpectTotalCount( 428 histogram_tester_.ExpectTotalCount(
386 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", 0); 429 "PageSerialization.MhtmlGeneration.PopupOverlaySkipped", 0);
387 } 430 }
388 431
389 TEST_F(WebFrameSerializerSanitizationTest, RemoveElements) { 432 TEST_F(WebFrameSerializerSanitizationTest, RemoveElements) {
390 String mhtml = 433 String mhtml =
391 GenerateMHTMLParts("http://www.test.com", "remove_elements.html"); 434 GenerateMHTMLFromHtml("http://www.test.com", "remove_elements.html");
392 LOG(ERROR) << mhtml;
393 435
394 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<script")); 436 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<script"));
395 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<noscript")); 437 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<noscript"));
396 438
397 // Only the meta element containing "Content-Security-Policy" is removed. 439 // Only the meta element containing "Content-Security-Policy" is removed.
398 // Other meta elements should be preserved. 440 // Other meta elements should be preserved.
399 EXPECT_EQ(WTF::kNotFound, 441 EXPECT_EQ(WTF::kNotFound,
400 mhtml.Find("<meta http-equiv=3D\"Content-Security-Policy")); 442 mhtml.Find("<meta http-equiv=3D\"Content-Security-Policy"));
401 EXPECT_NE(WTF::kNotFound, mhtml.Find("<meta name=3D\"description")); 443 EXPECT_NE(WTF::kNotFound, mhtml.Find("<meta name=3D\"description"));
402 EXPECT_NE(WTF::kNotFound, mhtml.Find("<meta http-equiv=3D\"refresh")); 444 EXPECT_NE(WTF::kNotFound, mhtml.Find("<meta http-equiv=3D\"refresh"));
403 445
404 // If an element is removed, its children should also be skipped. 446 // If an element is removed, its children should also be skipped.
405 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<select")); 447 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<select"));
406 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<option")); 448 EXPECT_EQ(WTF::kNotFound, mhtml.Find("<option"));
407 } 449 }
408 450
409 } // namespace blink 451 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698