DNS Prefetch fix: renderer shouldn't send long hostnames to browser.

R=ttuttle@chromium.org
BUG=464270

Review URL: https://codereview.chromium.org/1007323003

Cr-Commit-Position: refs/heads/master@{#321154}
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc
index 94d389f..6255237 100644
--- a/chrome/browser/net/predictor_browsertest.cc
+++ b/chrome/browser/net/predictor_browsertest.cc
@@ -30,6 +30,11 @@
 
 const char kBlinkPreconnectFeature[] = "LinkPreconnect";
 const char kChromiumHostname[] = "chromium.org";
+const char kInvalidLongHostname[] = "illegally-long-hostname-over-255-"
+    "characters-should-not-send-an-ipc-message-to-the-browser-"
+    "0000000000000000000000000000000000000000000000000000000000000000000000000"
+    "0000000000000000000000000000000000000000000000000000000000000000000000000"
+    "000000000000000000000000000000000000000000000000000000.org";
 
 // Records a history of all hostnames for which resolving has been requested,
 // and immediately fails the resolution requests themselves.
@@ -54,7 +59,11 @@
     return net::ERR_NAME_NOT_RESOLVED;
   }
 
-  bool HasHostBeenRequested(const std::string& hostname) {
+  int RequestedHostnameCount() const {
+    return requested_hostnames_.size();
+  }
+
+  bool HasHostBeenRequested(const std::string& hostname) const {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     return std::find(requested_hostnames_.begin(),
                      requested_hostnames_.end(),
@@ -210,10 +219,18 @@
     serializer.Serialize(*list_value);
   }
 
+  bool HasHostBeenRequested(const std::string& hostname) const {
+    return host_resolution_request_recorder_->HasHostBeenRequested(hostname);
+  }
+
   void WaitUntilHostHasBeenRequested(const std::string& hostname) {
     host_resolution_request_recorder_->WaitUntilHostHasBeenRequested(hostname);
   }
 
+  int RequestedHostnameCount() const {
+    return host_resolution_request_recorder_->RequestedHostnameCount();
+  }
+
   const GURL startup_url_;
   const GURL referring_url_;
   const GURL target_url_;
@@ -254,10 +271,13 @@
 
 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DnsPrefetch) {
   ASSERT_TRUE(test_server()->Start());
+  int hostnames_requested_before_load = RequestedHostnameCount();
   ui_test_utils::NavigateToURL(
       browser(),
       GURL(test_server()->GetURL("files/predictor/dns_prefetch.html")));
   WaitUntilHostHasBeenRequested(kChromiumHostname);
+  ASSERT_FALSE(HasHostBeenRequested(kInvalidLongHostname));
+  ASSERT_EQ(hostnames_requested_before_load + 1, RequestedHostnameCount());
 }
 
 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, Preconnect) {
diff --git a/chrome/test/data/predictor/dns_prefetch.html b/chrome/test/data/predictor/dns_prefetch.html
index ab2a63c0..c22c033 100644
--- a/chrome/test/data/predictor/dns_prefetch.html
+++ b/chrome/test/data/predictor/dns_prefetch.html
@@ -1 +1,2 @@
+<link rel="dns-prefetch" href="http://illegally-long-hostname-over-255-characters-should-not-send-an-ipc-message-to-the-browser-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.org/">
 <link rel="dns-prefetch" href="http://chromium.org/">
diff --git a/components/network_hints/renderer/renderer_dns_prefetch.cc b/components/network_hints/renderer/renderer_dns_prefetch.cc
index a9326b6..a1c38af 100644
--- a/components/network_hints/renderer/renderer_dns_prefetch.cc
+++ b/components/network_hints/renderer/renderer_dns_prefetch.cc
@@ -130,20 +130,23 @@
 void RendererDnsPrefetch::DnsPrefetchNames(size_t max_count) {
   // We are on the renderer thread, and just need to send things to the browser.
   NameList names;
+  size_t domains_handled = 0;
   for (DomainUseMap::iterator it = domain_map_.begin();
     it != domain_map_.end();
     ++it) {
     if (0 == (it->second & kLookupRequested)) {
       it->second |= kLookupRequested;
-      names.push_back(it->first);
+      domains_handled++;
+      if (it->first.length() <= network_hints::kMaxDnsHostnameLength)
+        names.push_back(it->first);
       if (0 == max_count) continue;  // Get all, independent of count.
       if (1 == max_count) break;
       --max_count;
       DCHECK_GE(max_count, 1u);
     }
   }
-  DCHECK_GE(new_name_count_, names.size());
-  new_name_count_ -= names.size();
+  DCHECK_GE(new_name_count_, domains_handled);
+  new_name_count_ -= domains_handled;
 
   network_hints::LookupRequest request;
   request.hostname_list = names;