Commit message: None
CVE: CVE-2013-0890
CWE: CWE-119
Vulnerability description: Multiple unspecified vulnerabilities in the IPC layer in Google Chrome before 25.0.1364.97 on Windows and Linux, and before 25.0.1364.99 on Mac OS X, allow remote attackers to cause a denial of service (memory corruption) or possibly have other impact via unknown vectors.

Project: Chrome

bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
  return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
          web_contents_->GetURL().SchemeIs(chrome::kHttpScheme));
}

Project: Chrome

  SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
      SafeBrowsingUIManager* ui_manager,
      WebContents* web_contents,
      const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) {
    if (unsafe_resources.size() == 1 &&
        (unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
         unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_PHISHING)) {
      return new SafeBrowsingBlockingPageV2(ui_manager, web_contents,
          unsafe_resources);
    }
    return new SafeBrowsingBlockingPageV1(ui_manager, web_contents,
                                          unsafe_resources);
  }

Project: Chrome

void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) {
  if (malware_details_ == NULL)
    return;  // Not all interstitials have malware details (eg phishing).

  if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled)) {
    BrowserThread::PostDelayedTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&MalwareDetails::FinishCollection, malware_details_.get()),
        base::TimeDelta::FromMilliseconds(delay_ms));
  }
}

Project: Chrome

std::string SafeBrowsingBlockingPageV1::GetHTMLContents() {
  DictionaryValue strings;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  std::string html;

  if (unsafe_resources_.empty()) {
    NOTREACHED();
    return std::string();
  }

  DCHECK_GT(unsafe_resources_.size(), 1U);
  PopulateMultipleThreatStringDictionary(&strings);
  html = rb.GetRawDataResource(
      IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK).as_string();
  interstitial_show_time_ = base::TimeTicks::Now();
  return jstemplate_builder::GetTemplatesHtml(html, &strings, "template_root");
}

Project: Chrome

std::string SafeBrowsingBlockingPageV2::GetHTMLContents() {
  DictionaryValue strings;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  std::string html;

  if (unsafe_resources_.empty()) {
    NOTREACHED();
    return std::string();
  }

  if (unsafe_resources_.size() > 1) {
    NOTREACHED();
  } else {
    SBThreatType threat_type = unsafe_resources_[0].threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE) {
      PopulateMalwareStringDictionary(&strings);
    } else {  // Phishing.
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      PopulatePhishingStringDictionary(&strings);
    }
    html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2).
        as_string();
  }
  interstitial_show_time_ = base::TimeTicks::Now();
  return jstemplate_builder::GetTemplatesHtml(html, &strings, "template-root");
}

Project: Chrome

bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked(
    const UnsafeResourceList& unsafe_resources) {
  if (unsafe_resources[0].threat_type ==
      SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
    return false;
  }

  return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource;
}

Project: Chrome

bool SafeBrowsingBlockingPage::IsPrefEnabled(const char* pref) {
  Profile* profile =
      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
  return profile->GetPrefs()->GetBoolean(pref);
}

Project: Chrome

void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
    SafeBrowsingUIManager* ui_manager,
    const UnsafeResourceList& unsafe_resources,
    bool proceed) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
                 ui_manager, unsafe_resources, proceed));
}

Project: Chrome

void SafeBrowsingBlockingPage::OnDontProceed() {
  RecordUserReactionTime(kNavigatedAwayMetaCommand);
  if (proceeded_)
    return;

  RecordUserAction(DONT_PROCEED);
  FinishMalwareDetails(0);  // No delay

  NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false);

  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
  if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
    NotifySafeBrowsingUIManager(ui_manager_, iter->second, false);
    unsafe_resource_map->erase(iter);
  }

  int last_committed_index =
      web_contents_->GetController().GetLastCommittedEntryIndex();
  if (navigation_entry_index_to_remove_ != -1 &&
      navigation_entry_index_to_remove_ != last_committed_index &&
      !web_contents_->IsBeingDestroyed()) {
    web_contents_->GetController().RemoveEntryAtIndex(
        navigation_entry_index_to_remove_);
    navigation_entry_index_to_remove_ = -1;
  }
}

Project: Chrome

void SafeBrowsingBlockingPage::OnProceed() {
  proceeded_ = true;
  RecordUserAction(PROCEED);
  FinishMalwareDetails(malware_details_proceed_delay_ms_);

  NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, true);

  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
  SafeBrowsingBlockingPage* blocking_page = NULL;
  if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
    blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_,
                                                     iter->second);
    unsafe_resource_map->erase(iter);
  }

  if (blocking_page)
    blocking_page->interstitial_page_->Show();
}

Project: Chrome

void SafeBrowsingBlockingPage::OverrideRendererPrefs(
      content::RendererPreferences* prefs) {
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
 }

Project: Chrome

void SafeBrowsingBlockingPageV1::PopulateMalwareStringDictionary(
    DictionaryValue* strings) {
  NOTREACHED();
}

Project: Chrome

void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary(
    DictionaryValue* strings) {
  std::string diagnostic_link = base::StringPrintf(kSbDiagnosticHtml,
      l10n_util::GetStringUTF8(
        IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE).c_str());

  string16 headline, description1, description2, description3;


  description3 = l10n_util::GetStringUTF16(
      IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3);
  if (is_main_frame_load_blocked_) {
    headline = l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE);
    description1 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1,
        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
        UTF8ToUTF16(url_.host()));
    description2 = l10n_util::GetStringUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2);
    strings->SetString("details", l10n_util::GetStringUTF16(
          IDS_SAFE_BROWSING_MALWARE_V2_DETAILS));
  } else {
    headline = l10n_util::GetStringUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE);
    description1 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE,
        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
        UTF8ToUTF16(web_contents_->GetURL().host()));
    description2 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE,
        UTF8ToUTF16(url_.host()));
    strings->SetString("details", l10n_util::GetStringFUTF16(
          IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE,
          UTF8ToUTF16(url_.host())));
  }

  PopulateStringDictionary(
      strings,
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE),
      headline,
      description1,
      description2,
      description3);

  if (!CanShowMalwareDetailsOption()) {
    strings->SetBoolean(kDisplayCheckBox, false);
    strings->SetString("confirm_text", "");
    strings->SetString(kBoxChecked, "");
  } else {
    strings->SetBoolean(kDisplayCheckBox, true);

    std::string privacy_link = base::StringPrintf(
        kPrivacyLinkHtml,
        l10n_util::GetStringUTF8(
            IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());

    strings->SetString("confirm_text",
                       l10n_util::GetStringFUTF16(
                           IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
                           UTF8ToUTF16(privacy_link)));
    if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled))
      strings->SetString(kBoxChecked, "yes");
    else
      strings->SetString(kBoxChecked, "");
  }

  strings->SetString("report_error", string16());
  strings->SetString("learnMore",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}

Project: Chrome

void SafeBrowsingBlockingPageV1::PopulateMultipleThreatStringDictionary(
    DictionaryValue* strings) {

  string16 malware_label =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_LABEL);
  string16 malware_link =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE);
  string16 phishing_label =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_LABEL);
  string16 phishing_link =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR);

  ListValue* error_strings = new ListValue;
  for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
       iter != unsafe_resources_.end(); ++iter) {
    const UnsafeResource& resource = *iter;
    SBThreatType threat_type = resource.threat_type;
    DictionaryValue* current_error_strings = new DictionaryValue;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE) {
      current_error_strings->SetString("type", "malware");
      current_error_strings->SetString("typeLabel", malware_label);
      current_error_strings->SetString("errorLink", malware_link);
    } else {
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      current_error_strings->SetString("type", "phishing");
      current_error_strings->SetString("typeLabel", phishing_label);
      current_error_strings->SetString("errorLink", phishing_link);
    }
    current_error_strings->SetString("url", resource.url.spec());
    error_strings->Append(current_error_strings);
  }
  strings->Set("errors", error_strings);

  switch (interstitial_type_) {
    case TYPE_MALWARE_AND_PHISHING:
      PopulateStringDictionary(
          strings,
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MULTI_THREAT_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1,
              UTF8ToUTF16(web_contents_->GetURL().host())),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2),
          string16());
      break;
    case TYPE_MALWARE:
      PopulateStringDictionary(
          strings,
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1,
              UTF8ToUTF16(web_contents_->GetURL().host())),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3));
      break;
    case TYPE_PHISHING:
      PopulateStringDictionary(
          strings,
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1,
              UTF8ToUTF16(web_contents_->GetURL().host())),
          string16(),
          string16());
      break;
  }

  strings->SetString("confirm_text",
                     l10n_util::GetStringUTF16(
                         IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE));
  strings->SetString("continue_button",
                     l10n_util::GetStringUTF16(
                         IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON));
  strings->SetString("back_button",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
  strings->SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
}

Project: Chrome

void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary(
    DictionaryValue* strings) {
  NOTREACHED();
}

Project: Chrome

void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary(
    DictionaryValue* strings) {
  PopulateStringDictionary(
      strings,
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE),
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE),
      l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1,
                                 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
                                 UTF8ToUTF16(url_.host())),
      string16(),
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2));

  strings->SetString("details", "");
  strings->SetString("confirm_text", "");
  strings->SetString(kBoxChecked, "");
  strings->SetString("report_error",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR));
  strings->SetBoolean(kDisplayCheckBox, false);
  strings->SetString("learnMore",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}

Project: Chrome

void SafeBrowsingBlockingPageV1::PopulateStringDictionary(
    DictionaryValue* strings,
    const string16& title,
    const string16& headline,
    const string16& description1,
    const string16& description2,
    const string16& description3) {
  strings->SetString("title", title);
  strings->SetString("headLine", headline);
  strings->SetString("description1", description1);
  strings->SetString("description2", description2);
  strings->SetString("description3", description3);
  strings->SetBoolean("proceedDisabled",
                      IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
}

Project: Chrome

void SafeBrowsingBlockingPageV2::PopulateStringDictionary(
    DictionaryValue* strings,
    const string16& title,
    const string16& headline,
    const string16& description1,
    const string16& description2,
    const string16& description3) {
  strings->SetString("title", title);
  strings->SetString("headLine", headline);
  strings->SetString("description1", description1);
  strings->SetString("description2", description2);
  strings->SetString("description3", description3);
  strings->SetBoolean("proceedDisabled",
                      IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
  strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_);
  strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING);

  strings->SetString("back_button",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
  strings->SetString("seeMore", l10n_util::GetStringUTF16(
      IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE));
  strings->SetString("proceed",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK));

  URLDataSource::SetFontAndTextDirection(strings);
}

Project: Chrome

void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) {
  enum {
    MALWARE_SHOW = 0,
    MALWARE_DONT_PROCEED,
    MALWARE_FORCED_DONT_PROCEED,
    MALWARE_PROCEED,
    MULTIPLE_SHOW,
    MULTIPLE_DONT_PROCEED,
    MULTIPLE_FORCED_DONT_PROCEED,
    MULTIPLE_PROCEED,
    PHISHING_SHOW,
    PHISHING_DONT_PROCEED,
    PHISHING_FORCED_DONT_PROCEED,
    PHISHING_PROCEED,
    MAX_ACTION
  } histogram_action = MAX_ACTION;

  switch (event) {
    case SHOW:
      switch (interstitial_type_) {
        case TYPE_MALWARE_AND_PHISHING:
          histogram_action = MULTIPLE_SHOW;
          break;
        case TYPE_MALWARE:
          histogram_action = MALWARE_SHOW;
          break;
        case TYPE_PHISHING:
          histogram_action = PHISHING_SHOW;
          break;
      }
      break;
    case PROCEED:
      switch (interstitial_type_) {
        case TYPE_MALWARE_AND_PHISHING:
          histogram_action = MULTIPLE_PROCEED;
          break;
        case TYPE_MALWARE:
          histogram_action = MALWARE_PROCEED;
          break;
        case TYPE_PHISHING:
          histogram_action = PHISHING_PROCEED;
          break;
      }
      break;
    case DONT_PROCEED:
      if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
        switch (interstitial_type_) {
          case TYPE_MALWARE_AND_PHISHING:
            histogram_action = MULTIPLE_FORCED_DONT_PROCEED;
            break;
          case TYPE_MALWARE:
            histogram_action = MALWARE_FORCED_DONT_PROCEED;
            break;
          case TYPE_PHISHING:
            histogram_action = PHISHING_FORCED_DONT_PROCEED;
            break;
        }
      } else {
        switch (interstitial_type_) {
          case TYPE_MALWARE_AND_PHISHING:
            histogram_action = MULTIPLE_DONT_PROCEED;
            break;
          case TYPE_MALWARE:
            histogram_action = MALWARE_DONT_PROCEED;
            break;
          case TYPE_PHISHING:
            histogram_action = PHISHING_DONT_PROCEED;
            break;
        }
      }
      break;
    default:
      NOTREACHED() << "Unexpected event: " << event;
  }
  if (histogram_action == MAX_ACTION) {
    NOTREACHED();
  } else {
    UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_action,
                              MAX_ACTION);
  }

  std::string action = "SBInterstitial";
  switch (interstitial_type_) {
    case TYPE_MALWARE_AND_PHISHING:
      action.append("Multiple");
      break;
    case TYPE_MALWARE:
      action.append("Malware");
      break;
    case TYPE_PHISHING:
      action.append("Phishing");
      break;
  }

  switch (event) {
    case SHOW:
      action.append("Show");
      break;
    case PROCEED:
      action.append("Proceed");
      break;
    case DONT_PROCEED:
      if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled))
        action.append("ForcedDontProceed");
      else
        action.append("DontProceed");
      break;
    default:
      NOTREACHED() << "Unexpected event: " << event;
  }

  content::RecordComputedAction(action);
}

Project: Chrome

void SafeBrowsingBlockingPage::RecordUserReactionTime(
    const std::string& command) {
  if (interstitial_show_time_.is_null())
    return;  // We already reported the user reaction time.
  base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_;
  DVLOG(1) << "User reaction time for command:" << command
           << " on interstitial_type_:" << interstitial_type_
           << " warning took " << dt.InMilliseconds() << "ms";
  bool recorded = true;
  if (interstitial_type_ == TYPE_MALWARE ||
      interstitial_type_ == TYPE_MALWARE_AND_PHISHING) {
    if (command == kProceedCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt);
    } else if (command == kTakeMeBackCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt);
    } else if (command == kShowDiagnosticCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt);
    } else if (command == kShowPrivacyCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy",
                                 dt);
    } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
                                 dt);
    } else if (command == kNavigatedAwayMetaCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt);
    } else if (command == kExpandedSeeMore) {
      if (has_expanded_see_more_section_)
        return;

      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
                                 dt);
      has_expanded_see_more_section_ = true;
      recorded = false;
    } else {
      recorded = false;
    }
  } else {
    if (command == kProceedCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt);
    } else if (command == kTakeMeBackCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt);
    } else if (command == kShowDiagnosticCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt);
    } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt);
    } else if (command == kNavigatedAwayMetaCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt);
    } else if (command == kExpandedSeeMore) {
      if (has_expanded_see_more_section_)
        return;

      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
                                 dt);
      has_expanded_see_more_section_ = true;
      recorded = false;
    } else {
      recorded = false;
    }
  }
  if (recorded)  // Making sure we don't double-count reaction times.
    interstitial_show_time_ = base::TimeTicks();  //  Resets the show time.
}

Project: Chrome

SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
    : malware_details_proceed_delay_ms_(
          kMalwareDetailsProceedDelayMilliSeconds),
      ui_manager_(ui_manager),
      report_loop_(NULL),
      is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)),
      unsafe_resources_(unsafe_resources),
      proceeded_(false),
      web_contents_(web_contents),
      url_(unsafe_resources[0].url),
      has_expanded_see_more_section_(false) {
  bool malware = false;
  bool phishing = false;
  for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
       iter != unsafe_resources_.end(); ++iter) {
    const UnsafeResource& resource = *iter;
    SBThreatType threat_type = resource.threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE) {
      malware = true;
    } else {
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      phishing = true;
    }
  }
  DCHECK(phishing || malware);
  if (malware && phishing)
    interstitial_type_ = TYPE_MALWARE_AND_PHISHING;
  else if (malware)
    interstitial_type_ = TYPE_MALWARE;
  else
    interstitial_type_ = TYPE_PHISHING;
  RecordUserAction(SHOW);
  if (!is_main_frame_load_blocked_) {
    navigation_entry_index_to_remove_ =
        web_contents->GetController().GetLastCommittedEntryIndex();
  } else {
    navigation_entry_index_to_remove_ = -1;
  }

  if (unsafe_resources.size() == 1 &&
      unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE &&
      malware_details_ == NULL &&
      CanShowMalwareDetailsOption()) {
    malware_details_ = MalwareDetails::NewMalwareDetails(
        ui_manager_, web_contents, unsafe_resources[0]);
  }

  interstitial_page_ = InterstitialPage::Create(
      web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this);
}

Project: Chrome

SafeBrowsingBlockingPageV1::SafeBrowsingBlockingPageV1(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
  : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
}

Project: Chrome

void SafeBrowsingBlockingPage::SetReportingPreference(bool report) {
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  PrefService* pref = profile->GetPrefs();
  pref->SetBoolean(prefs::kSafeBrowsingReportingEnabled, report);
}

Project: Chrome

void SafeBrowsingBlockingPage::ShowBlockingPage(
    SafeBrowsingUIManager* ui_manager,
    const UnsafeResource& unsafe_resource) {
  DVLOG(1) << __FUNCTION__ << " " << unsafe_resource.url.spec();
  WebContents* web_contents = tab_util::GetWebContentsByID(
      unsafe_resource.render_process_host_id, unsafe_resource.render_view_id);

  InterstitialPage* interstitial =
      InterstitialPage::GetInterstitialPage(web_contents);
  if (interstitial && !unsafe_resource.is_subresource) {
    interstitial->DontProceed();
    interstitial = NULL;
  }

  if (!interstitial) {
    std::vector<UnsafeResource> resources;
    resources.push_back(unsafe_resource);
    if (!factory_)
      factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer();
    SafeBrowsingBlockingPage* blocking_page =
        factory_->CreateSafeBrowsingPage(ui_manager, web_contents, resources);
    blocking_page->interstitial_page_->Show();
    return;
  }

  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  (*unsafe_resource_map)[web_contents].push_back(unsafe_resource);
}