OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chrome/renderer/safe_browsing/malware_dom_details.h" | |
6 | |
7 #include "base/compiler_specific.h" | |
8 #include "chrome/common/chrome_constants.h" | |
9 #include "chrome/common/safe_browsing/safebrowsing_messages.h" | |
10 #include "content/public/renderer/render_view.h" | |
11 #include "third_party/WebKit/public/platform/WebString.h" | |
12 #include "third_party/WebKit/public/web/WebDocument.h" | |
13 #include "third_party/WebKit/public/web/WebElement.h" | |
14 #include "third_party/WebKit/public/web/WebElementCollection.h" | |
15 #include "third_party/WebKit/public/web/WebFrame.h" | |
16 #include "third_party/WebKit/public/web/WebView.h" | |
17 | |
18 namespace safe_browsing { | |
19 | |
20 namespace { | |
21 | |
22 // Handler for the various HTML elements that we extract URLs from. | |
23 void HandleElement( | |
24 const blink::WebElement& element, | |
25 SafeBrowsingHostMsg_MalwareDOMDetails_Node* parent_node, | |
26 std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>* resources) { | |
27 if (!element.hasAttribute("src")) | |
28 return; | |
29 | |
30 // Retrieve the link and resolve the link in case it's relative. | |
31 blink::WebURL full_url = element.document().completeURL( | |
32 element.getAttribute("src")); | |
33 | |
34 const GURL& child_url = GURL(full_url); | |
35 | |
36 // Add to the parent node. | |
37 parent_node->children.push_back(child_url); | |
38 | |
39 // Create the child node. | |
40 SafeBrowsingHostMsg_MalwareDOMDetails_Node child_node; | |
41 child_node.url = child_url; | |
42 child_node.tag_name = element.tagName().utf8(); | |
43 child_node.parent = parent_node->url; | |
44 resources->push_back(child_node); | |
45 } | |
46 | |
47 } // namespace | |
48 | |
49 // An upper limit on the number of nodes we collect. | |
50 uint32 MalwareDOMDetails::kMaxNodes = 500; | |
51 | |
52 // static | |
53 MalwareDOMDetails* MalwareDOMDetails::Create(content::RenderView* render_view) { | |
54 // Private constructor and public static Create() method to facilitate | |
55 // stubbing out this class for binary-size reduction purposes. | |
56 return new MalwareDOMDetails(render_view); | |
57 } | |
58 | |
59 MalwareDOMDetails::MalwareDOMDetails(content::RenderView* render_view) | |
60 : content::RenderViewObserver(render_view) { | |
61 } | |
62 | |
63 MalwareDOMDetails::~MalwareDOMDetails() { | |
64 } | |
65 | |
66 bool MalwareDOMDetails::OnMessageReceived(const IPC::Message& message) { | |
67 bool handled = true; | |
68 IPC_BEGIN_MESSAGE_MAP(MalwareDOMDetails, message) | |
69 IPC_MESSAGE_HANDLER(SafeBrowsingMsg_GetMalwareDOMDetails, | |
70 OnGetMalwareDOMDetails) | |
71 IPC_MESSAGE_UNHANDLED(handled = false) | |
72 IPC_END_MESSAGE_MAP() | |
73 return handled; | |
74 } | |
75 | |
76 void MalwareDOMDetails::OnGetMalwareDOMDetails() { | |
77 std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> resources; | |
78 ExtractResources(&resources); | |
79 // Notify the browser. | |
80 render_view()->Send(new SafeBrowsingHostMsg_MalwareDOMDetails( | |
81 render_view()->GetRoutingID(), resources)); | |
82 } | |
83 | |
84 void MalwareDOMDetails::ExtractResources( | |
85 std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>* resources) { | |
86 blink::WebView* web_view = render_view()->GetWebView(); | |
87 if (!web_view) { | |
88 NOTREACHED(); | |
89 return; | |
90 } | |
91 blink::WebFrame* frame = web_view->mainFrame(); | |
92 for (; frame; frame = frame->traverseNext(false /* don't wrap */)) { | |
93 DCHECK(frame); | |
94 SafeBrowsingHostMsg_MalwareDOMDetails_Node details_node; | |
95 blink::WebDocument document = frame->document(); | |
96 details_node.url = GURL(document.url()); | |
97 if (document.isNull()) { | |
98 // Nothing in this frame, move on to the next one. | |
99 resources->push_back(details_node); | |
100 continue; | |
101 } | |
102 | |
103 blink::WebElementCollection elements = document.all(); | |
104 blink::WebElement element = elements.firstItem(); | |
105 for (; !element.isNull(); element = elements.nextItem()) { | |
106 if (element.hasHTMLTagName("iframe") || element.hasHTMLTagName("frame") || | |
107 element.hasHTMLTagName("embed") || element.hasHTMLTagName("script")) { | |
108 HandleElement(element, &details_node, resources); | |
109 if (resources->size() >= kMaxNodes) { | |
110 // We have reached kMaxNodes, exit early. | |
111 resources->push_back(details_node); | |
112 return; | |
113 } | |
114 } | |
115 } | |
116 | |
117 resources->push_back(details_node); | |
118 } | |
119 } | |
120 | |
121 } // namespace safe_browsing | |
OLD | NEW |