bool NavigationController::RendererDidNavigate(
    const ViewHostMsg_FrameNavigate_Params& params,
    int extra_invalidate_flags,
    LoadCommittedDetails* details) {

  if (GetLastCommittedEntry()) {
    details->previous_url = GetLastCommittedEntry()->url();
    details->previous_entry_index = last_committed_entry_index();
  } else {
    details->previous_url = GURL();
    details->previous_entry_index = -1;
  }

  if (pending_entry_index_ >= 0 && !pending_entry_->site_instance()) {
    DCHECK(pending_entry_->restore_type() != NavigationEntry::RESTORE_NONE);
    pending_entry_->set_site_instance(tab_contents_->GetSiteInstance());
    pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE);
  }

  details->is_in_page = IsURLInPageNavigation(params.url);

  details->type = ClassifyNavigation(params);

  switch (details->type) {
    case NavigationType::NEW_PAGE:
      RendererDidNavigateToNewPage(params, &(details->did_replace_entry));
      break;
    case NavigationType::EXISTING_PAGE:
      RendererDidNavigateToExistingPage(params);
      break;
    case NavigationType::SAME_PAGE:
      RendererDidNavigateToSamePage(params);
      break;
    case NavigationType::IN_PAGE:
      RendererDidNavigateInPage(params, &(details->did_replace_entry));
      break;
    case NavigationType::NEW_SUBFRAME:
      RendererDidNavigateNewSubframe(params);
      break;
    case NavigationType::AUTO_SUBFRAME:
      if (!RendererDidNavigateAutoSubframe(params))
         return false;
       break;
     case NavigationType::NAV_IGNORE:
       return false;
     default:
       NOTREACHED();
  }

  DCHECK(!params.content_state.empty());
  NavigationEntry* active_entry = GetActiveEntry();
  active_entry->set_content_state(params.content_state);

  DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance());

  details->is_auto = (PageTransition::IsRedirect(params.transition) &&
                      !pending_entry()) ||
      params.gesture == NavigationGestureAuto;

  details->entry = active_entry;
  details->is_main_frame = PageTransition::IsMainFrame(params.transition);
  details->serialized_security_info = params.security_info;
  details->http_status_code = params.http_status_code;
  NotifyNavigationEntryCommitted(details, extra_invalidate_flags);

  return true;
}

The drag-and-drop implementation in Google Chrome before 13.0.782.107 on Linux does not properly enforce permissions for files, which allows user-assisted remote attackers to bypass intended access restrictions via unspecified vectors.


bool NavigationController::RendererDidNavigate(
    const ViewHostMsg_FrameNavigate_Params& params,
    int extra_invalidate_flags,
    LoadCommittedDetails* details) {

  if (GetLastCommittedEntry()) {
    details->previous_url = GetLastCommittedEntry()->url();
    details->previous_entry_index = last_committed_entry_index();
  } else {
    details->previous_url = GURL();
    details->previous_entry_index = -1;
  }

  if (pending_entry_index_ >= 0 && !pending_entry_->site_instance()) {
    DCHECK(pending_entry_->restore_type() != NavigationEntry::RESTORE_NONE);
    pending_entry_->set_site_instance(tab_contents_->GetSiteInstance());
    pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE);
  }

  details->is_in_page = IsURLInPageNavigation(params.url);

  details->type = ClassifyNavigation(params);

  switch (details->type) {
    case NavigationType::NEW_PAGE:
      RendererDidNavigateToNewPage(params, &(details->did_replace_entry));
      break;
    case NavigationType::EXISTING_PAGE:
      RendererDidNavigateToExistingPage(params);
      break;
    case NavigationType::SAME_PAGE:
      RendererDidNavigateToSamePage(params);
      break;
    case NavigationType::IN_PAGE:
      RendererDidNavigateInPage(params, &(details->did_replace_entry));
      break;
    case NavigationType::NEW_SUBFRAME:
      RendererDidNavigateNewSubframe(params);
      break;
    case NavigationType::AUTO_SUBFRAME:
      if (!RendererDidNavigateAutoSubframe(params))
         return false;
       break;
     case NavigationType::NAV_IGNORE:
      // If a pending navigation was in progress, this canceled it.  We should
      // discard it and make sure it is removed from the URL bar.  After that,
      // there is nothing we can do with this navigation, so we just return to
      if (pending_entry_) {
        DiscardNonCommittedEntries();
        extra_invalidate_flags |= TabContents::INVALIDATE_URL;
        tab_contents_->NotifyNavigationStateChanged(extra_invalidate_flags);
      }
       return false;
     default:
       NOTREACHED();
  }

  DCHECK(!params.content_state.empty());
  NavigationEntry* active_entry = GetActiveEntry();
  active_entry->set_content_state(params.content_state);

  DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance());

  details->is_auto = (PageTransition::IsRedirect(params.transition) &&
                      !pending_entry()) ||
      params.gesture == NavigationGestureAuto;

  details->entry = active_entry;
  details->is_main_frame = PageTransition::IsMainFrame(params.transition);
  details->serialized_security_info = params.security_info;
  details->http_status_code = params.http_status_code;
  NotifyNavigationEntryCommitted(details, extra_invalidate_flags);

  return true;
}


bool Extension::InitFromValue(const DictionaryValue& source, int flags,
                              std::string* error) {
  URLPattern::ParseOption parse_strictness =
      (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT
                                   : URLPattern::PARSE_LENIENT);

  if (source.HasKey(keys::kPublicKey)) {
    std::string public_key_bytes;
    if (!source.GetString(keys::kPublicKey,
                          &public_key_) ||
        !ParsePEMKeyBytes(public_key_,
                          &public_key_bytes) ||
        !GenerateId(public_key_bytes, &id_)) {
      *error = errors::kInvalidKey;
      return false;
    }
  } else if (flags & REQUIRE_KEY) {
    *error = errors::kInvalidKey;
    return false;
  } else {
    id_ = Extension::GenerateIdForPath(path());
    if (id_.empty()) {
      NOTREACHED() << "Could not create ID from path.";
      return false;
    }
  }

  manifest_value_.reset(source.DeepCopy());

  extension_url_ = Extension::GetBaseURLFromExtensionId(id());

  std::string version_str;
  if (!source.GetString(keys::kVersion, &version_str)) {
    *error = errors::kInvalidVersion;
    return false;
  }
  version_.reset(Version::GetVersionFromString(version_str));
  if (!version_.get() ||
      version_->components().size() > 4) {
    *error = errors::kInvalidVersion;
    return false;
  }

  string16 localized_name;
  if (!source.GetString(keys::kName, &localized_name)) {
    *error = errors::kInvalidName;
    return false;
  }
  base::i18n::AdjustStringForLocaleDirection(&localized_name);
  name_ = UTF16ToUTF8(localized_name);

  if (source.HasKey(keys::kDescription)) {
    if (!source.GetString(keys::kDescription,
                          &description_)) {
      *error = errors::kInvalidDescription;
      return false;
    }
  }

  if (source.HasKey(keys::kHomepageURL)) {
    std::string tmp;
    if (!source.GetString(keys::kHomepageURL, &tmp)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidHomepageURL, "");
       return false;
     }
     homepage_url_ = GURL(tmp);
    if (!homepage_url_.is_valid()) {
       *error = ExtensionErrorUtils::FormatErrorMessage(
           errors::kInvalidHomepageURL, tmp);
       return false;
    }
  }

  if (source.HasKey(keys::kUpdateURL)) {
    std::string tmp;
    if (!source.GetString(keys::kUpdateURL, &tmp)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidUpdateURL, "");
      return false;
    }
    update_url_ = GURL(tmp);
    if (!update_url_.is_valid() ||
        update_url_.has_ref()) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidUpdateURL, tmp);
      return false;
    }
  }

  if (source.HasKey(keys::kMinimumChromeVersion)) {
    std::string minimum_version_string;
    if (!source.GetString(keys::kMinimumChromeVersion,
                          &minimum_version_string)) {
      *error = errors::kInvalidMinimumChromeVersion;
      return false;
    }

    scoped_ptr<Version> minimum_version(
        Version::GetVersionFromString(minimum_version_string));
    if (!minimum_version.get()) {
      *error = errors::kInvalidMinimumChromeVersion;
      return false;
    }

    chrome::VersionInfo current_version_info;
    if (!current_version_info.is_valid()) {
      NOTREACHED();
      return false;
    }

    scoped_ptr<Version> current_version(
        Version::GetVersionFromString(current_version_info.Version()));
    if (!current_version.get()) {
      DCHECK(false);
      return false;
    }

    if (current_version->CompareTo(*minimum_version) < 0) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kChromeVersionTooLow,
          l10n_util::GetStringUTF8(IDS_PRODUCT_NAME),
          minimum_version_string);
      return false;
    }
  }

  source.GetBoolean(keys::kConvertedFromUserScript,
                    &converted_from_user_script_);

  if (source.HasKey(keys::kIcons)) {
    DictionaryValue* icons_value = NULL;
    if (!source.GetDictionary(keys::kIcons, &icons_value)) {
      *error = errors::kInvalidIcons;
      return false;
    }

    for (size_t i = 0; i < arraysize(kIconSizes); ++i) {
      std::string key = base::IntToString(kIconSizes[i]);
      if (icons_value->HasKey(key)) {
        std::string icon_path;
        if (!icons_value->GetString(key, &icon_path)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidIconPath, key);
          return false;
        }

        if (!icon_path.empty() && icon_path[0] == '/')
          icon_path = icon_path.substr(1);

        if (icon_path.empty()) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidIconPath, key);
          return false;
        }

        icons_.Add(kIconSizes[i], icon_path);
      }
    }
  }

  is_theme_ = false;
  if (source.HasKey(keys::kTheme)) {
    if (ContainsNonThemeKeys(source)) {
      *error = errors::kThemesCannotContainExtensions;
      return false;
    }

    DictionaryValue* theme_value = NULL;
    if (!source.GetDictionary(keys::kTheme, &theme_value)) {
      *error = errors::kInvalidTheme;
      return false;
    }
    is_theme_ = true;

    DictionaryValue* images_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) {
      for (DictionaryValue::key_iterator iter = images_value->begin_keys();
           iter != images_value->end_keys(); ++iter) {
        std::string val;
        if (!images_value->GetString(*iter, &val)) {
          *error = errors::kInvalidThemeImages;
          return false;
        }
      }
      theme_images_.reset(images_value->DeepCopy());
    }

    DictionaryValue* colors_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) {
      for (DictionaryValue::key_iterator iter = colors_value->begin_keys();
           iter != colors_value->end_keys(); ++iter) {
        ListValue* color_list = NULL;
        double alpha = 0.0;
        int color = 0;
        if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) ||
            ((color_list->GetSize() != 3) &&
             ((color_list->GetSize() != 4) ||
              !color_list->GetDouble(3, &alpha))) ||
            !color_list->GetInteger(0, &color) ||
            !color_list->GetInteger(1, &color) ||
            !color_list->GetInteger(2, &color)) {
          *error = errors::kInvalidThemeColors;
          return false;
        }
      }
      theme_colors_.reset(colors_value->DeepCopy());
    }

    DictionaryValue* tints_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) {
      for (DictionaryValue::key_iterator iter = tints_value->begin_keys();
           iter != tints_value->end_keys(); ++iter) {
        ListValue* tint_list = NULL;
        double v = 0.0;
        if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) ||
            tint_list->GetSize() != 3 ||
            !tint_list->GetDouble(0, &v) ||
            !tint_list->GetDouble(1, &v) ||
            !tint_list->GetDouble(2, &v)) {
          *error = errors::kInvalidThemeTints;
          return false;
        }
      }
      theme_tints_.reset(tints_value->DeepCopy());
    }

    DictionaryValue* display_properties_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeDisplayProperties,
        &display_properties_value)) {
      theme_display_properties_.reset(
          display_properties_value->DeepCopy());
    }

    return true;
  }

  if (source.HasKey(keys::kPlugins)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kPlugins, &list_value)) {
      *error = errors::kInvalidPlugins;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* plugin_value = NULL;
      std::string path_str;
      bool is_public = false;

      if (!list_value->GetDictionary(i, &plugin_value)) {
        *error = errors::kInvalidPlugins;
        return false;
      }

      if (!plugin_value->GetString(keys::kPluginsPath, &path_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidPluginsPath, base::IntToString(i));
        return false;
      }

      if (plugin_value->HasKey(keys::kPluginsPublic)) {
        if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidPluginsPublic, base::IntToString(i));
          return false;
        }
      }

#if !defined(OS_CHROMEOS)
      plugins_.push_back(PluginInfo());
      plugins_.back().path = path().AppendASCII(path_str);
      plugins_.back().is_public = is_public;
#endif
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kNaClModules)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kNaClModules, &list_value)) {
      *error = errors::kInvalidNaClModules;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* module_value = NULL;
      std::string path_str;
      std::string mime_type;

      if (!list_value->GetDictionary(i, &module_value)) {
        *error = errors::kInvalidNaClModules;
        return false;
      }

      if (!module_value->GetString(keys::kNaClModulesPath, &path_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidNaClModulesPath, base::IntToString(i));
        return false;
      }

      if (!module_value->GetString(keys::kNaClModulesMIMEType, &mime_type)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidNaClModulesMIMEType, base::IntToString(i));
        return false;
      }

      nacl_modules_.push_back(NaClModuleInfo());
      nacl_modules_.back().url = GetResourceURL(path_str);
      nacl_modules_.back().mime_type = mime_type;
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kToolstrips)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kToolstrips, &list_value)) {
      *error = errors::kInvalidToolstrips;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      GURL toolstrip;
      DictionaryValue* toolstrip_value = NULL;
      std::string toolstrip_path;
      if (list_value->GetString(i, &toolstrip_path)) {
        toolstrip = GetResourceURL(toolstrip_path);
      } else if (list_value->GetDictionary(i, &toolstrip_value)) {
        if (!toolstrip_value->GetString(keys::kToolstripPath,
                                        &toolstrip_path)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidToolstrip, base::IntToString(i));
          return false;
        }
        toolstrip = GetResourceURL(toolstrip_path);
      } else {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidToolstrip, base::IntToString(i));
        return false;
      }
      toolstrips_.push_back(toolstrip);
    }
  }

  if (source.HasKey(keys::kContentScripts)) {
    ListValue* list_value;
    if (!source.GetList(keys::kContentScripts, &list_value)) {
      *error = errors::kInvalidContentScriptsList;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* content_script = NULL;
      if (!list_value->GetDictionary(i, &content_script)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidContentScript, base::IntToString(i));
        return false;
      }

      UserScript script;
      if (!LoadUserScriptHelper(content_script, i, flags, error, &script))
        return false;  // Failed to parse script context definition.
      script.set_extension_id(id());
      if (converted_from_user_script_) {
        script.set_emulate_greasemonkey(true);
        script.set_match_all_frames(true);  // Greasemonkey matches all frames.
      }
      content_scripts_.push_back(script);
    }
  }

  DictionaryValue* page_action_value = NULL;

  if (source.HasKey(keys::kPageActions)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kPageActions, &list_value)) {
      *error = errors::kInvalidPageActionsList;
      return false;
    }

    size_t list_value_length = list_value->GetSize();

    if (list_value_length == 0u) {
    } else if (list_value_length == 1u) {
      if (!list_value->GetDictionary(0, &page_action_value)) {
        *error = errors::kInvalidPageAction;
        return false;
      }
    } else {  // list_value_length > 1u.
      *error = errors::kInvalidPageActionsListSize;
      return false;
    }
  } else if (source.HasKey(keys::kPageAction)) {
    if (!source.GetDictionary(keys::kPageAction, &page_action_value)) {
      *error = errors::kInvalidPageAction;
      return false;
    }
  }

  if (page_action_value) {
    page_action_.reset(
        LoadExtensionActionHelper(page_action_value, error));
    if (!page_action_.get())
      return false;  // Failed to parse page action definition.
  }

  if (source.HasKey(keys::kBrowserAction)) {
    DictionaryValue* browser_action_value = NULL;
    if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) {
      *error = errors::kInvalidBrowserAction;
      return false;
    }

    browser_action_.reset(
        LoadExtensionActionHelper(browser_action_value, error));
    if (!browser_action_.get())
      return false;  // Failed to parse browser action definition.
  }

  if (source.HasKey(keys::kFileBrowserHandlers)) {
    ListValue* file_browser_handlers_value = NULL;
    if (!source.GetList(keys::kFileBrowserHandlers,
                              &file_browser_handlers_value)) {
      *error = errors::kInvalidFileBrowserHandler;
      return false;
    }

    file_browser_handlers_.reset(
        LoadFileBrowserHandlers(file_browser_handlers_value, error));
    if (!file_browser_handlers_.get())
      return false;  // Failed to parse file browser actions definition.
  }

  if (!LoadIsApp(manifest_value_.get(), error) ||
      !LoadExtent(manifest_value_.get(), keys::kWebURLs,
                  &extent_,
                  errors::kInvalidWebURLs, errors::kInvalidWebURL,
                  parse_strictness, error) ||
      !EnsureNotHybridApp(manifest_value_.get(), error) ||
      !LoadLaunchURL(manifest_value_.get(), error) ||
      !LoadLaunchContainer(manifest_value_.get(), error) ||
      !LoadAppIsolation(manifest_value_.get(), error)) {
    return false;
  }

  if (source.HasKey(keys::kOptionsPage)) {
    std::string options_str;
    if (!source.GetString(keys::kOptionsPage, &options_str)) {
      *error = errors::kInvalidOptionsPage;
      return false;
    }

    if (is_hosted_app()) {
      GURL options_url(options_str);
      if (!options_url.is_valid() ||
          !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) {
        *error = errors::kInvalidOptionsPageInHostedApp;
        return false;
      }
      options_url_ = options_url;
    } else {
      GURL absolute(options_str);
      if (absolute.is_valid()) {
        *error = errors::kInvalidOptionsPageExpectUrlInPackage;
        return false;
      }
      options_url_ = GetResourceURL(options_str);
      if (!options_url_.is_valid()) {
        *error = errors::kInvalidOptionsPage;
        return false;
      }
    }
  }

  if (source.HasKey(keys::kPermissions)) {
    ListValue* permissions = NULL;
    if (!source.GetList(keys::kPermissions, &permissions)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidPermissions, "");
      return false;
    }

    for (size_t i = 0; i < permissions->GetSize(); ++i) {
      std::string permission_str;
      if (!permissions->GetString(i, &permission_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidPermission, base::IntToString(i));
        return false;
      }

      if (!IsComponentOnlyPermission(permission_str)
#ifndef NDEBUG
           && !CommandLine::ForCurrentProcess()->HasSwitch(
                 switches::kExposePrivateExtensionApi)
#endif
          ) {
        continue;
      }

      if (permission_str == kOldUnlimitedStoragePermission)
        permission_str = kUnlimitedStoragePermission;

      if (web_extent().is_empty() || location() == Extension::COMPONENT) {
        if (IsAPIPermission(permission_str)) {
          if (permission_str == Extension::kExperimentalPermission &&
              !CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kEnableExperimentalExtensionApis) &&
              location() != Extension::COMPONENT) {
            *error = errors::kExperimentalFlagRequired;
            return false;
          }
          api_permissions_.insert(permission_str);
          continue;
        }
      } else {
        if (IsHostedAppPermission(permission_str)) {
          api_permissions_.insert(permission_str);
          continue;
        }
      }

      URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ?
          URLPattern::SCHEME_ALL : kValidHostPermissionSchemes);

      URLPattern::ParseResult parse_result = pattern.Parse(permission_str,
                                                           parse_strictness);
      if (parse_result == URLPattern::PARSE_SUCCESS) {
        if (!CanSpecifyHostPermission(pattern)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidPermissionScheme, base::IntToString(i));
          return false;
        }

        pattern.SetPath("/*");

        if (pattern.MatchesScheme(chrome::kFileScheme) &&
            !CanExecuteScriptEverywhere()) {
          wants_file_access_ = true;
          if (!(flags & ALLOW_FILE_ACCESS))
            pattern.set_valid_schemes(
                pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
        }

        host_permissions_.push_back(pattern);
      }

    }
  }

  if (source.HasKey(keys::kBackground)) {
    std::string background_str;
    if (!source.GetString(keys::kBackground, &background_str)) {
      *error = errors::kInvalidBackground;
      return false;
    }

    if (is_hosted_app()) {
      if (api_permissions_.find(kBackgroundPermission) ==
          api_permissions_.end()) {
        *error = errors::kBackgroundPermissionNeeded;
        return false;
      }
      GURL bg_page(background_str);
      if (!bg_page.is_valid()) {
        *error = errors::kInvalidBackgroundInHostedApp;
        return false;
      }

      if (!(bg_page.SchemeIs("https") ||
           (CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kAllowHTTPBackgroundPage) &&
            bg_page.SchemeIs("http")))) {
        *error = errors::kInvalidBackgroundInHostedApp;
        return false;
      }
      background_url_ = bg_page;
    } else {
      background_url_ = GetResourceURL(background_str);
    }
  }

  if (source.HasKey(keys::kDefaultLocale)) {
    if (!source.GetString(keys::kDefaultLocale, &default_locale_) ||
        !l10n_util::IsValidLocaleSyntax(default_locale_)) {
      *error = errors::kInvalidDefaultLocale;
      return false;
    }
  }

  if (source.HasKey(keys::kChromeURLOverrides)) {
    DictionaryValue* overrides = NULL;
    if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) {
      *error = errors::kInvalidChromeURLOverrides;
      return false;
    }

    for (DictionaryValue::key_iterator iter = overrides->begin_keys();
         iter != overrides->end_keys(); ++iter) {
      std::string page = *iter;
      std::string val;
      if ((page != chrome::kChromeUINewTabHost &&
#if defined(TOUCH_UI)
           page != chrome::kChromeUIKeyboardHost &&
#endif
#if defined(OS_CHROMEOS)
           page != chrome::kChromeUIActivationMessageHost &&
#endif
           page != chrome::kChromeUIBookmarksHost &&
           page != chrome::kChromeUIHistoryHost) ||
          !overrides->GetStringWithoutPathExpansion(*iter, &val)) {
        *error = errors::kInvalidChromeURLOverrides;
        return false;
      }
      chrome_url_overrides_[page] = GetResourceURL(val);
    }

    if (overrides->size() > 1) {
      *error = errors::kMultipleOverrides;
      return false;
    }
  }

  if (source.HasKey(keys::kOmnibox)) {
    if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
        omnibox_keyword_.empty()) {
      *error = errors::kInvalidOmniboxKeyword;
      return false;
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kContentSecurityPolicy)) {
    std::string content_security_policy;
    if (!source.GetString(keys::kContentSecurityPolicy,
                          &content_security_policy)) {
      *error = errors::kInvalidContentSecurityPolicy;
      return false;
    }
    const char kBadCSPCharacters[] = {'\r', '\n', '\0'};
    if (content_security_policy.find_first_of(kBadCSPCharacters, 0,
                                              arraysize(kBadCSPCharacters)) !=
        std::string::npos) {
      *error = errors::kInvalidContentSecurityPolicy;
      return false;
    }
    content_security_policy_ = content_security_policy;
  }

  if (source.HasKey(keys::kDevToolsPage)) {
    std::string devtools_str;
    if (!source.GetString(keys::kDevToolsPage, &devtools_str)) {
      *error = errors::kInvalidDevToolsPage;
      return false;
    }
    if (!HasApiPermission(Extension::kExperimentalPermission)) {
      *error = errors::kDevToolsExperimental;
      return false;
    }
    devtools_url_ = GetResourceURL(devtools_str);
  }

  if (source.HasKey(keys::kSidebar)) {
    DictionaryValue* sidebar_value = NULL;
    if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) {
      *error = errors::kInvalidSidebar;
      return false;
    }
    if (!HasApiPermission(Extension::kExperimentalPermission)) {
      *error = errors::kSidebarExperimental;
      return false;
    }
    sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error));
    if (!sidebar_defaults_.get())
      return false;  // Failed to parse sidebar definition.
  }

  if (source.HasKey(keys::kTts)) {
    DictionaryValue* tts_dict = NULL;
    if (!source.GetDictionary(keys::kTts, &tts_dict)) {
      *error = errors::kInvalidTts;
      return false;
    }

    if (tts_dict->HasKey(keys::kTtsVoices)) {
      ListValue* tts_voices = NULL;
      if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) {
        *error = errors::kInvalidTtsVoices;
        return false;
      }

      for (size_t i = 0; i < tts_voices->GetSize(); i++) {
        DictionaryValue* one_tts_voice = NULL;
        if (!tts_voices->GetDictionary(i, &one_tts_voice)) {
          *error = errors::kInvalidTtsVoices;
          return false;
        }

        TtsVoice voice_data;
        if (one_tts_voice->HasKey(keys::kTtsVoicesVoiceName)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesVoiceName, &voice_data.voice_name)) {
            *error = errors::kInvalidTtsVoicesVoiceName;
            return false;
          }
        }
        if (one_tts_voice->HasKey(keys::kTtsVoicesLocale)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesLocale, &voice_data.locale) ||
              !l10n_util::IsValidLocaleSyntax(voice_data.locale)) {
            *error = errors::kInvalidTtsVoicesLocale;
            return false;
          }
        }
        if (one_tts_voice->HasKey(keys::kTtsVoicesGender)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesGender, &voice_data.gender) ||
              (voice_data.gender != keys::kTtsGenderMale &&
               voice_data.gender != keys::kTtsGenderFemale)) {
            *error = errors::kInvalidTtsVoicesGender;
            return false;
          }
        }

        tts_voices_.push_back(voice_data);
      }
    }
  }

  incognito_split_mode_ = is_app();
  if (source.HasKey(keys::kIncognito)) {
    std::string value;
    if (!source.GetString(keys::kIncognito, &value)) {
      *error = errors::kInvalidIncognitoBehavior;
      return false;
    }
    if (value == values::kIncognitoSpanning) {
      incognito_split_mode_ = false;
    } else if (value == values::kIncognitoSplit) {
      incognito_split_mode_ = true;
    } else {
      *error = errors::kInvalidIncognitoBehavior;
      return false;
    }
  }

  if (HasMultipleUISurfaces()) {
    *error = errors::kOneUISurfaceOnly;
    return false;
  }

  InitEffectiveHostPermissions();

  DCHECK(source.Equals(manifest_value_.get()));

  return true;
}

The extensions implementation in Google Chrome before 13.0.782.107 does not properly validate the URL for the home page, which allows remote attackers to have an unspecified impact via a crafted extension.


bool Extension::InitFromValue(const DictionaryValue& source, int flags,
                              std::string* error) {
  URLPattern::ParseOption parse_strictness =
      (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT
                                   : URLPattern::PARSE_LENIENT);

  if (source.HasKey(keys::kPublicKey)) {
    std::string public_key_bytes;
    if (!source.GetString(keys::kPublicKey,
                          &public_key_) ||
        !ParsePEMKeyBytes(public_key_,
                          &public_key_bytes) ||
        !GenerateId(public_key_bytes, &id_)) {
      *error = errors::kInvalidKey;
      return false;
    }
  } else if (flags & REQUIRE_KEY) {
    *error = errors::kInvalidKey;
    return false;
  } else {
    id_ = Extension::GenerateIdForPath(path());
    if (id_.empty()) {
      NOTREACHED() << "Could not create ID from path.";
      return false;
    }
  }

  manifest_value_.reset(source.DeepCopy());

  extension_url_ = Extension::GetBaseURLFromExtensionId(id());

  std::string version_str;
  if (!source.GetString(keys::kVersion, &version_str)) {
    *error = errors::kInvalidVersion;
    return false;
  }
  version_.reset(Version::GetVersionFromString(version_str));
  if (!version_.get() ||
      version_->components().size() > 4) {
    *error = errors::kInvalidVersion;
    return false;
  }

  string16 localized_name;
  if (!source.GetString(keys::kName, &localized_name)) {
    *error = errors::kInvalidName;
    return false;
  }
  base::i18n::AdjustStringForLocaleDirection(&localized_name);
  name_ = UTF16ToUTF8(localized_name);

  if (source.HasKey(keys::kDescription)) {
    if (!source.GetString(keys::kDescription,
                          &description_)) {
      *error = errors::kInvalidDescription;
      return false;
    }
  }

  if (source.HasKey(keys::kHomepageURL)) {
    std::string tmp;
    if (!source.GetString(keys::kHomepageURL, &tmp)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidHomepageURL, "");
       return false;
     }
     homepage_url_ = GURL(tmp);
    if (!homepage_url_.is_valid() ||
        (!homepage_url_.SchemeIs("http") &&
            !homepage_url_.SchemeIs("https"))) {
       *error = ExtensionErrorUtils::FormatErrorMessage(
           errors::kInvalidHomepageURL, tmp);
       return false;
    }
  }

  if (source.HasKey(keys::kUpdateURL)) {
    std::string tmp;
    if (!source.GetString(keys::kUpdateURL, &tmp)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidUpdateURL, "");
      return false;
    }
    update_url_ = GURL(tmp);
    if (!update_url_.is_valid() ||
        update_url_.has_ref()) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidUpdateURL, tmp);
      return false;
    }
  }

  if (source.HasKey(keys::kMinimumChromeVersion)) {
    std::string minimum_version_string;
    if (!source.GetString(keys::kMinimumChromeVersion,
                          &minimum_version_string)) {
      *error = errors::kInvalidMinimumChromeVersion;
      return false;
    }

    scoped_ptr<Version> minimum_version(
        Version::GetVersionFromString(minimum_version_string));
    if (!minimum_version.get()) {
      *error = errors::kInvalidMinimumChromeVersion;
      return false;
    }

    chrome::VersionInfo current_version_info;
    if (!current_version_info.is_valid()) {
      NOTREACHED();
      return false;
    }

    scoped_ptr<Version> current_version(
        Version::GetVersionFromString(current_version_info.Version()));
    if (!current_version.get()) {
      DCHECK(false);
      return false;
    }

    if (current_version->CompareTo(*minimum_version) < 0) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kChromeVersionTooLow,
          l10n_util::GetStringUTF8(IDS_PRODUCT_NAME),
          minimum_version_string);
      return false;
    }
  }

  source.GetBoolean(keys::kConvertedFromUserScript,
                    &converted_from_user_script_);

  if (source.HasKey(keys::kIcons)) {
    DictionaryValue* icons_value = NULL;
    if (!source.GetDictionary(keys::kIcons, &icons_value)) {
      *error = errors::kInvalidIcons;
      return false;
    }

    for (size_t i = 0; i < arraysize(kIconSizes); ++i) {
      std::string key = base::IntToString(kIconSizes[i]);
      if (icons_value->HasKey(key)) {
        std::string icon_path;
        if (!icons_value->GetString(key, &icon_path)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidIconPath, key);
          return false;
        }

        if (!icon_path.empty() && icon_path[0] == '/')
          icon_path = icon_path.substr(1);

        if (icon_path.empty()) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidIconPath, key);
          return false;
        }

        icons_.Add(kIconSizes[i], icon_path);
      }
    }
  }

  is_theme_ = false;
  if (source.HasKey(keys::kTheme)) {
    if (ContainsNonThemeKeys(source)) {
      *error = errors::kThemesCannotContainExtensions;
      return false;
    }

    DictionaryValue* theme_value = NULL;
    if (!source.GetDictionary(keys::kTheme, &theme_value)) {
      *error = errors::kInvalidTheme;
      return false;
    }
    is_theme_ = true;

    DictionaryValue* images_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) {
      for (DictionaryValue::key_iterator iter = images_value->begin_keys();
           iter != images_value->end_keys(); ++iter) {
        std::string val;
        if (!images_value->GetString(*iter, &val)) {
          *error = errors::kInvalidThemeImages;
          return false;
        }
      }
      theme_images_.reset(images_value->DeepCopy());
    }

    DictionaryValue* colors_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) {
      for (DictionaryValue::key_iterator iter = colors_value->begin_keys();
           iter != colors_value->end_keys(); ++iter) {
        ListValue* color_list = NULL;
        double alpha = 0.0;
        int color = 0;
        if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) ||
            ((color_list->GetSize() != 3) &&
             ((color_list->GetSize() != 4) ||
              !color_list->GetDouble(3, &alpha))) ||
            !color_list->GetInteger(0, &color) ||
            !color_list->GetInteger(1, &color) ||
            !color_list->GetInteger(2, &color)) {
          *error = errors::kInvalidThemeColors;
          return false;
        }
      }
      theme_colors_.reset(colors_value->DeepCopy());
    }

    DictionaryValue* tints_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) {
      for (DictionaryValue::key_iterator iter = tints_value->begin_keys();
           iter != tints_value->end_keys(); ++iter) {
        ListValue* tint_list = NULL;
        double v = 0.0;
        if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) ||
            tint_list->GetSize() != 3 ||
            !tint_list->GetDouble(0, &v) ||
            !tint_list->GetDouble(1, &v) ||
            !tint_list->GetDouble(2, &v)) {
          *error = errors::kInvalidThemeTints;
          return false;
        }
      }
      theme_tints_.reset(tints_value->DeepCopy());
    }

    DictionaryValue* display_properties_value = NULL;
    if (theme_value->GetDictionary(keys::kThemeDisplayProperties,
        &display_properties_value)) {
      theme_display_properties_.reset(
          display_properties_value->DeepCopy());
    }

    return true;
  }

  if (source.HasKey(keys::kPlugins)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kPlugins, &list_value)) {
      *error = errors::kInvalidPlugins;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* plugin_value = NULL;
      std::string path_str;
      bool is_public = false;

      if (!list_value->GetDictionary(i, &plugin_value)) {
        *error = errors::kInvalidPlugins;
        return false;
      }

      if (!plugin_value->GetString(keys::kPluginsPath, &path_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidPluginsPath, base::IntToString(i));
        return false;
      }

      if (plugin_value->HasKey(keys::kPluginsPublic)) {
        if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidPluginsPublic, base::IntToString(i));
          return false;
        }
      }

#if !defined(OS_CHROMEOS)
      plugins_.push_back(PluginInfo());
      plugins_.back().path = path().AppendASCII(path_str);
      plugins_.back().is_public = is_public;
#endif
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kNaClModules)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kNaClModules, &list_value)) {
      *error = errors::kInvalidNaClModules;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* module_value = NULL;
      std::string path_str;
      std::string mime_type;

      if (!list_value->GetDictionary(i, &module_value)) {
        *error = errors::kInvalidNaClModules;
        return false;
      }

      if (!module_value->GetString(keys::kNaClModulesPath, &path_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidNaClModulesPath, base::IntToString(i));
        return false;
      }

      if (!module_value->GetString(keys::kNaClModulesMIMEType, &mime_type)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidNaClModulesMIMEType, base::IntToString(i));
        return false;
      }

      nacl_modules_.push_back(NaClModuleInfo());
      nacl_modules_.back().url = GetResourceURL(path_str);
      nacl_modules_.back().mime_type = mime_type;
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kToolstrips)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kToolstrips, &list_value)) {
      *error = errors::kInvalidToolstrips;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      GURL toolstrip;
      DictionaryValue* toolstrip_value = NULL;
      std::string toolstrip_path;
      if (list_value->GetString(i, &toolstrip_path)) {
        toolstrip = GetResourceURL(toolstrip_path);
      } else if (list_value->GetDictionary(i, &toolstrip_value)) {
        if (!toolstrip_value->GetString(keys::kToolstripPath,
                                        &toolstrip_path)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidToolstrip, base::IntToString(i));
          return false;
        }
        toolstrip = GetResourceURL(toolstrip_path);
      } else {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidToolstrip, base::IntToString(i));
        return false;
      }
      toolstrips_.push_back(toolstrip);
    }
  }

  if (source.HasKey(keys::kContentScripts)) {
    ListValue* list_value;
    if (!source.GetList(keys::kContentScripts, &list_value)) {
      *error = errors::kInvalidContentScriptsList;
      return false;
    }

    for (size_t i = 0; i < list_value->GetSize(); ++i) {
      DictionaryValue* content_script = NULL;
      if (!list_value->GetDictionary(i, &content_script)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidContentScript, base::IntToString(i));
        return false;
      }

      UserScript script;
      if (!LoadUserScriptHelper(content_script, i, flags, error, &script))
        return false;  // Failed to parse script context definition.
      script.set_extension_id(id());
      if (converted_from_user_script_) {
        script.set_emulate_greasemonkey(true);
        script.set_match_all_frames(true);  // Greasemonkey matches all frames.
      }
      content_scripts_.push_back(script);
    }
  }

  DictionaryValue* page_action_value = NULL;

  if (source.HasKey(keys::kPageActions)) {
    ListValue* list_value = NULL;
    if (!source.GetList(keys::kPageActions, &list_value)) {
      *error = errors::kInvalidPageActionsList;
      return false;
    }

    size_t list_value_length = list_value->GetSize();

    if (list_value_length == 0u) {
    } else if (list_value_length == 1u) {
      if (!list_value->GetDictionary(0, &page_action_value)) {
        *error = errors::kInvalidPageAction;
        return false;
      }
    } else {  // list_value_length > 1u.
      *error = errors::kInvalidPageActionsListSize;
      return false;
    }
  } else if (source.HasKey(keys::kPageAction)) {
    if (!source.GetDictionary(keys::kPageAction, &page_action_value)) {
      *error = errors::kInvalidPageAction;
      return false;
    }
  }

  if (page_action_value) {
    page_action_.reset(
        LoadExtensionActionHelper(page_action_value, error));
    if (!page_action_.get())
      return false;  // Failed to parse page action definition.
  }

  if (source.HasKey(keys::kBrowserAction)) {
    DictionaryValue* browser_action_value = NULL;
    if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) {
      *error = errors::kInvalidBrowserAction;
      return false;
    }

    browser_action_.reset(
        LoadExtensionActionHelper(browser_action_value, error));
    if (!browser_action_.get())
      return false;  // Failed to parse browser action definition.
  }

  if (source.HasKey(keys::kFileBrowserHandlers)) {
    ListValue* file_browser_handlers_value = NULL;
    if (!source.GetList(keys::kFileBrowserHandlers,
                              &file_browser_handlers_value)) {
      *error = errors::kInvalidFileBrowserHandler;
      return false;
    }

    file_browser_handlers_.reset(
        LoadFileBrowserHandlers(file_browser_handlers_value, error));
    if (!file_browser_handlers_.get())
      return false;  // Failed to parse file browser actions definition.
  }

  if (!LoadIsApp(manifest_value_.get(), error) ||
      !LoadExtent(manifest_value_.get(), keys::kWebURLs,
                  &extent_,
                  errors::kInvalidWebURLs, errors::kInvalidWebURL,
                  parse_strictness, error) ||
      !EnsureNotHybridApp(manifest_value_.get(), error) ||
      !LoadLaunchURL(manifest_value_.get(), error) ||
      !LoadLaunchContainer(manifest_value_.get(), error) ||
      !LoadAppIsolation(manifest_value_.get(), error)) {
    return false;
  }

  if (source.HasKey(keys::kOptionsPage)) {
    std::string options_str;
    if (!source.GetString(keys::kOptionsPage, &options_str)) {
      *error = errors::kInvalidOptionsPage;
      return false;
    }

    if (is_hosted_app()) {
      GURL options_url(options_str);
      if (!options_url.is_valid() ||
          !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) {
        *error = errors::kInvalidOptionsPageInHostedApp;
        return false;
      }
      options_url_ = options_url;
    } else {
      GURL absolute(options_str);
      if (absolute.is_valid()) {
        *error = errors::kInvalidOptionsPageExpectUrlInPackage;
        return false;
      }
      options_url_ = GetResourceURL(options_str);
      if (!options_url_.is_valid()) {
        *error = errors::kInvalidOptionsPage;
        return false;
      }
    }
  }

  if (source.HasKey(keys::kPermissions)) {
    ListValue* permissions = NULL;
    if (!source.GetList(keys::kPermissions, &permissions)) {
      *error = ExtensionErrorUtils::FormatErrorMessage(
          errors::kInvalidPermissions, "");
      return false;
    }

    for (size_t i = 0; i < permissions->GetSize(); ++i) {
      std::string permission_str;
      if (!permissions->GetString(i, &permission_str)) {
        *error = ExtensionErrorUtils::FormatErrorMessage(
            errors::kInvalidPermission, base::IntToString(i));
        return false;
      }

      if (!IsComponentOnlyPermission(permission_str)
#ifndef NDEBUG
           && !CommandLine::ForCurrentProcess()->HasSwitch(
                 switches::kExposePrivateExtensionApi)
#endif
          ) {
        continue;
      }

      if (permission_str == kOldUnlimitedStoragePermission)
        permission_str = kUnlimitedStoragePermission;

      if (web_extent().is_empty() || location() == Extension::COMPONENT) {
        if (IsAPIPermission(permission_str)) {
          if (permission_str == Extension::kExperimentalPermission &&
              !CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kEnableExperimentalExtensionApis) &&
              location() != Extension::COMPONENT) {
            *error = errors::kExperimentalFlagRequired;
            return false;
          }
          api_permissions_.insert(permission_str);
          continue;
        }
      } else {
        if (IsHostedAppPermission(permission_str)) {
          api_permissions_.insert(permission_str);
          continue;
        }
      }

      URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ?
          URLPattern::SCHEME_ALL : kValidHostPermissionSchemes);

      URLPattern::ParseResult parse_result = pattern.Parse(permission_str,
                                                           parse_strictness);
      if (parse_result == URLPattern::PARSE_SUCCESS) {
        if (!CanSpecifyHostPermission(pattern)) {
          *error = ExtensionErrorUtils::FormatErrorMessage(
              errors::kInvalidPermissionScheme, base::IntToString(i));
          return false;
        }

        pattern.SetPath("/*");

        if (pattern.MatchesScheme(chrome::kFileScheme) &&
            !CanExecuteScriptEverywhere()) {
          wants_file_access_ = true;
          if (!(flags & ALLOW_FILE_ACCESS))
            pattern.set_valid_schemes(
                pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
        }

        host_permissions_.push_back(pattern);
      }

    }
  }

  if (source.HasKey(keys::kBackground)) {
    std::string background_str;
    if (!source.GetString(keys::kBackground, &background_str)) {
      *error = errors::kInvalidBackground;
      return false;
    }

    if (is_hosted_app()) {
      if (api_permissions_.find(kBackgroundPermission) ==
          api_permissions_.end()) {
        *error = errors::kBackgroundPermissionNeeded;
        return false;
      }
      GURL bg_page(background_str);
      if (!bg_page.is_valid()) {
        *error = errors::kInvalidBackgroundInHostedApp;
        return false;
      }

      if (!(bg_page.SchemeIs("https") ||
           (CommandLine::ForCurrentProcess()->HasSwitch(
                switches::kAllowHTTPBackgroundPage) &&
            bg_page.SchemeIs("http")))) {
        *error = errors::kInvalidBackgroundInHostedApp;
        return false;
      }
      background_url_ = bg_page;
    } else {
      background_url_ = GetResourceURL(background_str);
    }
  }

  if (source.HasKey(keys::kDefaultLocale)) {
    if (!source.GetString(keys::kDefaultLocale, &default_locale_) ||
        !l10n_util::IsValidLocaleSyntax(default_locale_)) {
      *error = errors::kInvalidDefaultLocale;
      return false;
    }
  }

  if (source.HasKey(keys::kChromeURLOverrides)) {
    DictionaryValue* overrides = NULL;
    if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) {
      *error = errors::kInvalidChromeURLOverrides;
      return false;
    }

    for (DictionaryValue::key_iterator iter = overrides->begin_keys();
         iter != overrides->end_keys(); ++iter) {
      std::string page = *iter;
      std::string val;
      if ((page != chrome::kChromeUINewTabHost &&
#if defined(TOUCH_UI)
           page != chrome::kChromeUIKeyboardHost &&
#endif
#if defined(OS_CHROMEOS)
           page != chrome::kChromeUIActivationMessageHost &&
#endif
           page != chrome::kChromeUIBookmarksHost &&
           page != chrome::kChromeUIHistoryHost) ||
          !overrides->GetStringWithoutPathExpansion(*iter, &val)) {
        *error = errors::kInvalidChromeURLOverrides;
        return false;
      }
      chrome_url_overrides_[page] = GetResourceURL(val);
    }

    if (overrides->size() > 1) {
      *error = errors::kMultipleOverrides;
      return false;
    }
  }

  if (source.HasKey(keys::kOmnibox)) {
    if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
        omnibox_keyword_.empty()) {
      *error = errors::kInvalidOmniboxKeyword;
      return false;
    }
  }

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis) &&
      source.HasKey(keys::kContentSecurityPolicy)) {
    std::string content_security_policy;
    if (!source.GetString(keys::kContentSecurityPolicy,
                          &content_security_policy)) {
      *error = errors::kInvalidContentSecurityPolicy;
      return false;
    }
    const char kBadCSPCharacters[] = {'\r', '\n', '\0'};
    if (content_security_policy.find_first_of(kBadCSPCharacters, 0,
                                              arraysize(kBadCSPCharacters)) !=
        std::string::npos) {
      *error = errors::kInvalidContentSecurityPolicy;
      return false;
    }
    content_security_policy_ = content_security_policy;
  }

  if (source.HasKey(keys::kDevToolsPage)) {
    std::string devtools_str;
    if (!source.GetString(keys::kDevToolsPage, &devtools_str)) {
      *error = errors::kInvalidDevToolsPage;
      return false;
    }
    if (!HasApiPermission(Extension::kExperimentalPermission)) {
      *error = errors::kDevToolsExperimental;
      return false;
    }
    devtools_url_ = GetResourceURL(devtools_str);
  }

  if (source.HasKey(keys::kSidebar)) {
    DictionaryValue* sidebar_value = NULL;
    if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) {
      *error = errors::kInvalidSidebar;
      return false;
    }
    if (!HasApiPermission(Extension::kExperimentalPermission)) {
      *error = errors::kSidebarExperimental;
      return false;
    }
    sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error));
    if (!sidebar_defaults_.get())
      return false;  // Failed to parse sidebar definition.
  }

  if (source.HasKey(keys::kTts)) {
    DictionaryValue* tts_dict = NULL;
    if (!source.GetDictionary(keys::kTts, &tts_dict)) {
      *error = errors::kInvalidTts;
      return false;
    }

    if (tts_dict->HasKey(keys::kTtsVoices)) {
      ListValue* tts_voices = NULL;
      if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) {
        *error = errors::kInvalidTtsVoices;
        return false;
      }

      for (size_t i = 0; i < tts_voices->GetSize(); i++) {
        DictionaryValue* one_tts_voice = NULL;
        if (!tts_voices->GetDictionary(i, &one_tts_voice)) {
          *error = errors::kInvalidTtsVoices;
          return false;
        }

        TtsVoice voice_data;
        if (one_tts_voice->HasKey(keys::kTtsVoicesVoiceName)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesVoiceName, &voice_data.voice_name)) {
            *error = errors::kInvalidTtsVoicesVoiceName;
            return false;
          }
        }
        if (one_tts_voice->HasKey(keys::kTtsVoicesLocale)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesLocale, &voice_data.locale) ||
              !l10n_util::IsValidLocaleSyntax(voice_data.locale)) {
            *error = errors::kInvalidTtsVoicesLocale;
            return false;
          }
        }
        if (one_tts_voice->HasKey(keys::kTtsVoicesGender)) {
          if (!one_tts_voice->GetString(
                  keys::kTtsVoicesGender, &voice_data.gender) ||
              (voice_data.gender != keys::kTtsGenderMale &&
               voice_data.gender != keys::kTtsGenderFemale)) {
            *error = errors::kInvalidTtsVoicesGender;
            return false;
          }
        }

        tts_voices_.push_back(voice_data);
      }
    }
  }

  incognito_split_mode_ = is_app();
  if (source.HasKey(keys::kIncognito)) {
    std::string value;
    if (!source.GetString(keys::kIncognito, &value)) {
      *error = errors::kInvalidIncognitoBehavior;
      return false;
    }
    if (value == values::kIncognitoSpanning) {
      incognito_split_mode_ = false;
    } else if (value == values::kIncognitoSplit) {
      incognito_split_mode_ = true;
    } else {
      *error = errors::kInvalidIncognitoBehavior;
      return false;
    }
  }

  if (HasMultipleUISurfaces()) {
    *error = errors::kOneUISurfaceOnly;
    return false;
  }

  InitEffectiveHostPermissions();

  DCHECK(source.Equals(manifest_value_.get()));

  return true;
}


bool TypedUrlModelAssociator::AssociateModels() {
  VLOG(1) << "Associating TypedUrl Models";
  DCHECK(expected_loop_ == MessageLoop::current());

  std::vector<history::URLRow> typed_urls;
  if (!history_backend_->GetAllTypedURLs(&typed_urls)) {
    LOG(ERROR) << "Could not get the typed_url entries.";
    return false;
  }

  std::map<history::URLID, history::VisitVector> visit_vectors;
  for (std::vector<history::URLRow>::iterator ix = typed_urls.begin();
       ix != typed_urls.end(); ++ix) {
    if (!history_backend_->GetVisitsForURL(ix->id(),
                                           &(visit_vectors[ix->id()]))) {
      LOG(ERROR) << "Could not get the url's visits.";
      return false;
    }
    if (visit_vectors[ix->id()].empty()) {
      history::VisitRow visit(
          ix->id(), ix->last_visit(), 0, PageTransition::TYPED, 0);
      visit_vectors[ix->id()].push_back(visit);
    }
  }

  TypedUrlTitleVector titles;
  TypedUrlVector new_urls;
  TypedUrlVisitVector new_visits;
  TypedUrlUpdateVector updated_urls;

  {
    sync_api::WriteTransaction trans(sync_service_->GetUserShare());
    sync_api::ReadNode typed_url_root(&trans);
    if (!typed_url_root.InitByTagLookup(kTypedUrlTag)) {
      LOG(ERROR) << "Server did not create the top-level typed_url node. We "
                 << "might be running against an out-of-date server.";
      return false;
    }

    std::set<std::string> current_urls;
    for (std::vector<history::URLRow>::iterator ix = typed_urls.begin();
         ix != typed_urls.end(); ++ix) {
      std::string tag = ix->url().spec();

      history::VisitVector& visits = visit_vectors[ix->id()];

      sync_api::ReadNode node(&trans);
      if (node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) {
        const sync_pb::TypedUrlSpecifics& typed_url(
            node.GetTypedUrlSpecifics());
        DCHECK_EQ(tag, typed_url.url());

        history::URLRow new_url(*ix);

        std::vector<history::VisitInfo> added_visits;
        int difference = MergeUrls(typed_url, *ix, &visits, &new_url,
                                   &added_visits);
        if (difference & DIFF_UPDATE_NODE) {
          sync_api::WriteNode write_node(&trans);
          if (!write_node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) {
            LOG(ERROR) << "Failed to edit typed_url sync node.";
            return false;
          }
          if (typed_url.visits_size() > 0) {
            base::Time earliest_visit =
                base::Time::FromInternalValue(typed_url.visits(0));
            for (history::VisitVector::iterator it = visits.begin();
                 it != visits.end() && it->visit_time < earliest_visit; ) {
              it = visits.erase(it);
            }
             DCHECK(visits.size() > 0);
          } else {
            NOTREACHED() << "Syncing typed URL with no visits: " <<
                typed_url.url();
           }
           WriteToSyncNode(new_url, visits, &write_node);
         }
        if (difference & DIFF_LOCAL_TITLE_CHANGED) {
          titles.push_back(std::pair<GURL, string16>(new_url.url(),
                                                     new_url.title()));
        }
        if (difference & DIFF_LOCAL_ROW_CHANGED) {
          updated_urls.push_back(
              std::pair<history::URLID, history::URLRow>(ix->id(), new_url));
        }
        if (difference & DIFF_LOCAL_VISITS_ADDED) {
          new_visits.push_back(
              std::pair<GURL, std::vector<history::VisitInfo> >(ix->url(),
                                                                added_visits));
        }

        Associate(&tag, node.GetId());
      } else {
        sync_api::WriteNode node(&trans);
        if (!node.InitUniqueByCreation(syncable::TYPED_URLS,
                                       typed_url_root, tag)) {
          LOG(ERROR) << "Failed to create typed_url sync node.";
          return false;
        }

        node.SetTitle(UTF8ToWide(tag));
        WriteToSyncNode(*ix, visits, &node);

        Associate(&tag, node.GetId());
      }

      current_urls.insert(tag);
    }

    int64 sync_child_id = typed_url_root.GetFirstChildId();
    while (sync_child_id != sync_api::kInvalidId) {
      sync_api::ReadNode sync_child_node(&trans);
      if (!sync_child_node.InitByIdLookup(sync_child_id)) {
        LOG(ERROR) << "Failed to fetch child node.";
        return false;
      }
       const sync_pb::TypedUrlSpecifics& typed_url(
         sync_child_node.GetTypedUrlSpecifics());

       if (current_urls.find(typed_url.url()) == current_urls.end()) {
         new_visits.push_back(
             std::pair<GURL, std::vector<history::VisitInfo> >(
                GURL(typed_url.url()),
                std::vector<history::VisitInfo>()));
        std::vector<history::VisitInfo>& visits = new_visits.back().second;
        history::URLRow new_url(GURL(typed_url.url()));
        TypedUrlModelAssociator::UpdateURLRowFromTypedUrlSpecifics(
            typed_url, &new_url);

        for (int c = 0; c < typed_url.visits_size(); ++c) {
          DCHECK(c == 0 || typed_url.visits(c) > typed_url.visits(c - 1));
          DCHECK_LE(typed_url.visit_transitions(c),
                    static_cast<int>(PageTransition::LAST_CORE));
          visits.push_back(history::VisitInfo(
              base::Time::FromInternalValue(typed_url.visits(c)),
              static_cast<PageTransition::Type>(
                  typed_url.visit_transitions(c))));
        }

         Associate(&typed_url.url(), sync_child_node.GetId());
         new_urls.push_back(new_url);
       }
      sync_child_id = sync_child_node.GetSuccessorId();
     }
   }

  return WriteToHistoryBackend(&titles, &new_urls, &updated_urls,
                               &new_visits, NULL);
}

Use-after-free vulnerability in Google Chrome before 13.0.782.107 allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to the frame loader.


bool TypedUrlModelAssociator::AssociateModels() {
  VLOG(1) << "Associating TypedUrl Models";
  DCHECK(expected_loop_ == MessageLoop::current());

  std::vector<history::URLRow> typed_urls;
  if (!history_backend_->GetAllTypedURLs(&typed_urls)) {
    LOG(ERROR) << "Could not get the typed_url entries.";
    return false;
  }

  std::map<history::URLID, history::VisitVector> visit_vectors;
  for (std::vector<history::URLRow>::iterator ix = typed_urls.begin();
       ix != typed_urls.end(); ++ix) {
    if (!history_backend_->GetVisitsForURL(ix->id(),
                                           &(visit_vectors[ix->id()]))) {
      LOG(ERROR) << "Could not get the url's visits.";
      return false;
    }
    if (visit_vectors[ix->id()].empty()) {
      history::VisitRow visit(
          ix->id(), ix->last_visit(), 0, PageTransition::TYPED, 0);
      visit_vectors[ix->id()].push_back(visit);
    }
  }

  TypedUrlTitleVector titles;
  TypedUrlVector new_urls;
  TypedUrlVisitVector new_visits;
  TypedUrlUpdateVector updated_urls;

  {
    sync_api::WriteTransaction trans(sync_service_->GetUserShare());
    sync_api::ReadNode typed_url_root(&trans);
    if (!typed_url_root.InitByTagLookup(kTypedUrlTag)) {
      LOG(ERROR) << "Server did not create the top-level typed_url node. We "
                 << "might be running against an out-of-date server.";
      return false;
    }

    std::set<std::string> current_urls;
    for (std::vector<history::URLRow>::iterator ix = typed_urls.begin();
         ix != typed_urls.end(); ++ix) {
      std::string tag = ix->url().spec();

      history::VisitVector& visits = visit_vectors[ix->id()];

      sync_api::ReadNode node(&trans);
      if (node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) {
        const sync_pb::TypedUrlSpecifics& typed_url(
            node.GetTypedUrlSpecifics());
        DCHECK_EQ(tag, typed_url.url());

        history::URLRow new_url(*ix);

        std::vector<history::VisitInfo> added_visits;
        int difference = MergeUrls(typed_url, *ix, &visits, &new_url,
                                   &added_visits);
        if (difference & DIFF_UPDATE_NODE) {
          sync_api::WriteNode write_node(&trans);
          if (!write_node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) {
            LOG(ERROR) << "Failed to edit typed_url sync node.";
            return false;
          }
          if (typed_url.visits_size() > 0) {
            base::Time earliest_visit =
                base::Time::FromInternalValue(typed_url.visits(0));
            for (history::VisitVector::iterator it = visits.begin();
                 it != visits.end() && it->visit_time < earliest_visit; ) {
              it = visits.erase(it);
            }
             DCHECK(visits.size() > 0);
           }
           WriteToSyncNode(new_url, visits, &write_node);
         }
        if (difference & DIFF_LOCAL_TITLE_CHANGED) {
          titles.push_back(std::pair<GURL, string16>(new_url.url(),
                                                     new_url.title()));
        }
        if (difference & DIFF_LOCAL_ROW_CHANGED) {
          updated_urls.push_back(
              std::pair<history::URLID, history::URLRow>(ix->id(), new_url));
        }
        if (difference & DIFF_LOCAL_VISITS_ADDED) {
          new_visits.push_back(
              std::pair<GURL, std::vector<history::VisitInfo> >(ix->url(),
                                                                added_visits));
        }

        Associate(&tag, node.GetId());
      } else {
        sync_api::WriteNode node(&trans);
        if (!node.InitUniqueByCreation(syncable::TYPED_URLS,
                                       typed_url_root, tag)) {
          LOG(ERROR) << "Failed to create typed_url sync node.";
          return false;
        }

        node.SetTitle(UTF8ToWide(tag));
        WriteToSyncNode(*ix, visits, &node);

        Associate(&tag, node.GetId());
      }

      current_urls.insert(tag);
    }

    int64 sync_child_id = typed_url_root.GetFirstChildId();
    while (sync_child_id != sync_api::kInvalidId) {
      sync_api::ReadNode sync_child_node(&trans);
      if (!sync_child_node.InitByIdLookup(sync_child_id)) {
        LOG(ERROR) << "Failed to fetch child node.";
        return false;
      }
       const sync_pb::TypedUrlSpecifics& typed_url(
         sync_child_node.GetTypedUrlSpecifics());

      sync_child_id = sync_child_node.GetSuccessorId();

      // Ignore old sync nodes that don't have any transition data stored with
      // them.
      if (typed_url.visit_transitions_size() == 0) {
        VLOG(1) << "Ignoring obsolete sync node with no visit transition info.";
        continue;
      }

       if (current_urls.find(typed_url.url()) == current_urls.end()) {
         new_visits.push_back(
             std::pair<GURL, std::vector<history::VisitInfo> >(
                GURL(typed_url.url()),
                std::vector<history::VisitInfo>()));
        std::vector<history::VisitInfo>& visits = new_visits.back().second;
        history::URLRow new_url(GURL(typed_url.url()));
        TypedUrlModelAssociator::UpdateURLRowFromTypedUrlSpecifics(
            typed_url, &new_url);

        for (int c = 0; c < typed_url.visits_size(); ++c) {
          DCHECK(c == 0 || typed_url.visits(c) > typed_url.visits(c - 1));
          DCHECK_LE(typed_url.visit_transitions(c),
                    static_cast<int>(PageTransition::LAST_CORE));
          visits.push_back(history::VisitInfo(
              base::Time::FromInternalValue(typed_url.visits(c)),
              static_cast<PageTransition::Type>(
                  typed_url.visit_transitions(c))));
        }

         Associate(&typed_url.url(), sync_child_node.GetId());
         new_urls.push_back(new_url);
       }
     }
   }

  return WriteToHistoryBackend(&titles, &new_urls, &updated_urls,
                               &new_visits, NULL);
}


LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
{
    if (h.isFixed())
        return computeContentBoxLogicalHeight(h.value());

    if (isRenderView())
        return isHorizontalWritingMode() ? toRenderView(this)->frameView()->visibleHeight() : toRenderView(this)->frameView()->visibleWidth();

     if (isTableCell() && (h.isAuto() || h.isPercent()))
         return overrideHeight() - borderAndPaddingLogicalWidth();

    if (h.isPercent())
       return computeContentBoxLogicalHeight(h.calcValue(containingBlock()->availableLogicalHeight()));

    if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
        RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
        LayoutUnit oldHeight = block->logicalHeight();
        block->computeLogicalHeight();
        LayoutUnit newHeight = block->computeContentBoxLogicalHeight(block->contentLogicalHeight());
        block->setLogicalHeight(oldHeight);
        return computeContentBoxLogicalHeight(newHeight);
    }

    return containingBlock()->availableLogicalHeight();
}

Google Chrome before 11.0.696.68 does not properly perform casts of variables during interaction with the WebKit engine, which allows remote attackers to cause a denial of service or possibly have unspecified other impact via unknown vectors.


LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
{
    if (h.isFixed())
        return computeContentBoxLogicalHeight(h.value());

    if (isRenderView())
        return isHorizontalWritingMode() ? toRenderView(this)->frameView()->visibleHeight() : toRenderView(this)->frameView()->visibleWidth();

     if (isTableCell() && (h.isAuto() || h.isPercent()))
         return overrideHeight() - borderAndPaddingLogicalWidth();

    if (h.isPercent()) {
        LayoutUnit availableHeight;
        // https://bugs.webkit.org/show_bug.cgi?id=64046
        // For absolutely positioned elements whose containing block is based on a block-level element,
        // the percentage is calculated with respect to the height of the padding box of that element
        if (isPositioned())
            availableHeight = containingBlockLogicalHeightForPositioned(containingBlock());
        else
            availableHeight = containingBlock()->availableLogicalHeight();
        return computeContentBoxLogicalHeight(h.calcValue(availableHeight));
    }

    if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
        RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
        LayoutUnit oldHeight = block->logicalHeight();
        block->computeLogicalHeight();
        LayoutUnit newHeight = block->computeContentBoxLogicalHeight(block->contentLogicalHeight());
        block->setLogicalHeight(oldHeight);
        return computeContentBoxLogicalHeight(newHeight);
    }

    return containingBlock()->availableLogicalHeight();
}


   void FocusFirstNameField() {
     LOG(WARNING) << "Clicking on the tab.";
    ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
                                                       VIEW_ID_TAB_CONTAINER));
    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                             VIEW_ID_TAB_CONTAINER));

     LOG(WARNING) << "Focusing the first name field.";
     bool result = false;
    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
        render_view_host(), L"",
        L"if (document.readyState === 'complete')"
        L"  document.getElementById('firstname').focus();"
        L"else"
        L"  domAutomationController.send(false);",
        &result));
    ASSERT_TRUE(result);
  }

Buffer overflow in the SSE2 optimization functionality in Google Chrome before 22.0.1229.79 allows remote attackers to cause a denial of service or possibly have unspecified other impact via unknown vectors.


   void FocusFirstNameField() {
     LOG(WARNING) << "Clicking on the tab.";
    ui_test_utils::SimulateMouseClick(browser()->GetSelectedWebContents());

     LOG(WARNING) << "Focusing the first name field.";
     bool result = false;
    ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
        render_view_host(), L"",
        L"if (document.readyState === 'complete')"
        L"  document.getElementById('firstname').focus();"
        L"else"
        L"  domAutomationController.send(false);",
        &result));
    ASSERT_TRUE(result);
  }


 bool BaseSettingChange::Init(Profile* profile) {
  DCHECK(profile);
   profile_ = profile;
   return true;
 }

Skia, as used in Google Chrome before 22.0.1229.79, allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors that trigger an out-of-bounds write operation, a different vulnerability than CVE-2012-2883.


 bool BaseSettingChange::Init(Profile* profile) {
  DCHECK(profile && !profile_);
   profile_ = profile;
   return true;
 }


 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
     xmlNodePtr cur = NULL;
     long val;
     xmlChar str[30];
     xmlDocPtr doc;

     if (nargs == 0) {
 	cur = ctxt->context->node;
     } else if (nargs == 1) {
	xmlXPathObjectPtr obj;
 	xmlNodeSetPtr nodelist;
 	int i, ret;

	if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
	    ctxt->error = XPATH_INVALID_TYPE;
	    xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"generate-id() : invalid arg expecting a node-set\n");
	    return;
	}
	obj = valuePop(ctxt);
	nodelist = obj->nodesetval;
	if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
	    xmlXPathFreeObject(obj);
	    valuePush(ctxt, xmlXPathNewCString(""));
	    return;
	}
	cur = nodelist->nodeTab[0];
	for (i = 1;i < nodelist->nodeNr;i++) {
	    ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
 	    if (ret == -1)
 	        cur = nodelist->nodeTab[i];
 	}
	xmlXPathFreeObject(obj);
     } else {
 	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
 		"generate-id() : invalid number of args %d\n", nargs);
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    /*
     * Okay this is ugly but should work, use the NodePtr address
     * to forge the ID
     */
    if (cur->type != XML_NAMESPACE_DECL)
        doc = cur->doc;
    else {
        xmlNsPtr ns = (xmlNsPtr) cur;

        if (ns->context != NULL)
            doc = ns->context;
        else
            doc = ctxt->context->doc;

     }

     val = (long)((char *)cur - (char *)doc);
     if (val >= 0) {
       sprintf((char *)str, "idp%ld", val);
    } else {
      sprintf((char *)str, "idm%ld", -val);
    }
    valuePush(ctxt, xmlXPathNewString(str));
}

libxslt 1.1.26 and earlier, as used in Google Chrome before 21.0.1180.89, does not properly manage memory, which might allow remote attackers to cause a denial of service (application crash) via a crafted XSLT expression that is not properly identified during XPath navigation, related to (1) the xsltCompileLocationPathPattern function in libxslt/pattern.c and (2) the xsltGenerateIdFunction function in libxslt/functions.c.


 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
     xmlNodePtr cur = NULL;
    xmlXPathObjectPtr obj = NULL;
     long val;
     xmlChar str[30];
     xmlDocPtr doc;

     if (nargs == 0) {
 	cur = ctxt->context->node;
     } else if (nargs == 1) {
 	xmlNodeSetPtr nodelist;
 	int i, ret;

	if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
	    ctxt->error = XPATH_INVALID_TYPE;
	    xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
		"generate-id() : invalid arg expecting a node-set\n");
	    return;
	}
	obj = valuePop(ctxt);
	nodelist = obj->nodesetval;
	if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
	    xmlXPathFreeObject(obj);
	    valuePush(ctxt, xmlXPathNewCString(""));
	    return;
	}
	cur = nodelist->nodeTab[0];
	for (i = 1;i < nodelist->nodeNr;i++) {
	    ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
 	    if (ret == -1)
 	        cur = nodelist->nodeTab[i];
 	}
     } else {
 	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
 		"generate-id() : invalid number of args %d\n", nargs);
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    /*
     * Okay this is ugly but should work, use the NodePtr address
     * to forge the ID
     */
    if (cur->type != XML_NAMESPACE_DECL)
        doc = cur->doc;
    else {
        xmlNsPtr ns = (xmlNsPtr) cur;

        if (ns->context != NULL)
            doc = ns->context;
        else
            doc = ctxt->context->doc;

     }

    if (obj)
        xmlXPathFreeObject(obj);

     val = (long)((char *)cur - (char *)doc);
     if (val >= 0) {
       sprintf((char *)str, "idp%ld", val);
    } else {
      sprintf((char *)str, "idm%ld", -val);
    }
    valuePush(ctxt, xmlXPathNewString(str));
}


SSLErrorInfo SSLErrorInfo::CreateError(ErrorType error_type,
                                       net::X509Certificate* cert,
                                       const GURL& request_url) {
  string16 title, details, short_description;
  std::vector<string16> extra_info;
  switch (error_type) {
    case CERT_COMMON_NAME_INVALID: {
      title =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_TITLE);
      std::vector<std::string> dns_names;
      cert->GetDNSNames(&dns_names);
      DCHECK(!dns_names.empty());
      size_t i = 0;
      for (; i < dns_names.size(); ++i) {
        if (dns_names[i] == cert->subject().common_name)
          break;
      }
      if (i == dns_names.size())
        i = 0;
       details =
           l10n_util::GetStringFUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
                                      UTF8ToUTF16(request_url.host()),
                                     UTF8ToUTF16(dns_names[i]),
                                      UTF8ToUTF16(request_url.host()));
       short_description = l10n_util::GetStringUTF16(
           IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
       extra_info.push_back(
           l10n_util::GetStringFUTF16(
               IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2,
              UTF8ToUTF16(cert->subject().common_name),
               UTF8ToUTF16(request_url.host())));
       break;
     }
    case CERT_DATE_INVALID:
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      if (cert->HasExpired()) {
        title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_TITLE);
        details = l10n_util::GetStringFUTF16(
            IDS_CERT_ERROR_EXPIRED_DETAILS,
            UTF8ToUTF16(request_url.host()),
            UTF8ToUTF16(request_url.host()),
            base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
        short_description =
            l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DESCRIPTION);
        extra_info.push_back(l10n_util::GetStringUTF16(
            IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2));
      } else {
        title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_TITLE);
        details = l10n_util::GetStringFUTF16(
            IDS_CERT_ERROR_NOT_YET_VALID_DETAILS,
            UTF8ToUTF16(request_url.host()),
            UTF8ToUTF16(request_url.host()),
            base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
        short_description =
            l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION);
        extra_info.push_back(
            l10n_util::GetStringUTF16(
                IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2));
      }
      break;
    case CERT_AUTHORITY_INVALID:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2,
          UTF8ToUTF16(request_url.host()),
          UTF8ToUTF16(request_url.host())));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_3));
      break;
    case CERT_CONTAINS_ERRORS:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringFUTF16(IDS_CERT_ERROR_EXTRA_INFO_1,
                                     UTF8ToUTF16(request_url.host())));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2));
      break;
    case CERT_NO_REVOCATION_MECHANISM:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE);
      details = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS);
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION);
      break;
    case CERT_UNABLE_TO_CHECK_REVOCATION:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE);
      details = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS);
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION);
      break;
    case CERT_REVOKED:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_TITLE);
      details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_REVOKED_CERT_DETAILS,
                                           UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2));
      break;
    case CERT_INVALID:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_INVALID_CERT_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_INVALID_CERT_EXTRA_INFO_2));
      break;
    case CERT_WEAK_SIGNATURE_ALGORITHM:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(
              IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2));
      break;
    case CERT_WEAK_KEY:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_WEAK_KEY_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_WEAK_KEY_DETAILS, UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(
              IDS_CERT_ERROR_WEAK_KEY_EXTRA_INFO_2));
      break;
    case UNKNOWN:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE);
      details = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS);
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
      break;
    default:
      NOTREACHED();
  }
  return SSLErrorInfo(title, details, short_description, extra_info);
}

Cross-site scripting (XSS) vulnerability in an SSL interstitial page in Google Chrome before 21.0.1180.89 allows remote attackers to inject arbitrary web script or HTML via unspecified vectors.


SSLErrorInfo SSLErrorInfo::CreateError(ErrorType error_type,
                                       net::X509Certificate* cert,
                                       const GURL& request_url) {
  string16 title, details, short_description;
  std::vector<string16> extra_info;
  switch (error_type) {
    case CERT_COMMON_NAME_INVALID: {
      title =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_TITLE);
      std::vector<std::string> dns_names;
      cert->GetDNSNames(&dns_names);
      DCHECK(!dns_names.empty());
      size_t i = 0;
      for (; i < dns_names.size(); ++i) {
        if (dns_names[i] == cert->subject().common_name)
          break;
      }
      if (i == dns_names.size())
        i = 0;
       details =
           l10n_util::GetStringFUTF16(IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS,
                                      UTF8ToUTF16(request_url.host()),
                                     net::EscapeForHTML(
                                         UTF8ToUTF16(dns_names[i])),
                                      UTF8ToUTF16(request_url.host()));
       short_description = l10n_util::GetStringUTF16(
           IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
       extra_info.push_back(
           l10n_util::GetStringFUTF16(
               IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2,
              net::EscapeForHTML(UTF8ToUTF16(cert->subject().common_name)),
               UTF8ToUTF16(request_url.host())));
       break;
     }
    case CERT_DATE_INVALID:
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      if (cert->HasExpired()) {
        title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_TITLE);
        details = l10n_util::GetStringFUTF16(
            IDS_CERT_ERROR_EXPIRED_DETAILS,
            UTF8ToUTF16(request_url.host()),
            UTF8ToUTF16(request_url.host()),
            base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
        short_description =
            l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXPIRED_DESCRIPTION);
        extra_info.push_back(l10n_util::GetStringUTF16(
            IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2));
      } else {
        title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_TITLE);
        details = l10n_util::GetStringFUTF16(
            IDS_CERT_ERROR_NOT_YET_VALID_DETAILS,
            UTF8ToUTF16(request_url.host()),
            UTF8ToUTF16(request_url.host()),
            base::TimeFormatFriendlyDateAndTime(base::Time::Now()));
        short_description =
            l10n_util::GetStringUTF16(IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION);
        extra_info.push_back(
            l10n_util::GetStringUTF16(
                IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2));
      }
      break;
    case CERT_AUTHORITY_INVALID:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2,
          UTF8ToUTF16(request_url.host()),
          UTF8ToUTF16(request_url.host())));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_3));
      break;
    case CERT_CONTAINS_ERRORS:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringFUTF16(IDS_CERT_ERROR_EXTRA_INFO_1,
                                     UTF8ToUTF16(request_url.host())));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2));
      break;
    case CERT_NO_REVOCATION_MECHANISM:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE);
      details = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS);
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION);
      break;
    case CERT_UNABLE_TO_CHECK_REVOCATION:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE);
      details = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS);
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION);
      break;
    case CERT_REVOKED:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_TITLE);
      details = l10n_util::GetStringFUTF16(IDS_CERT_ERROR_REVOKED_CERT_DETAILS,
                                           UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2));
      break;
    case CERT_INVALID:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_INVALID_CERT_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_INVALID_CERT_EXTRA_INFO_2));
      break;
    case CERT_WEAK_SIGNATURE_ALGORITHM:
      title = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS,
          UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(
              IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2));
      break;
    case CERT_WEAK_KEY:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_WEAK_KEY_TITLE);
      details = l10n_util::GetStringFUTF16(
          IDS_CERT_ERROR_WEAK_KEY_DETAILS, UTF8ToUTF16(request_url.host()));
      short_description = l10n_util::GetStringUTF16(
          IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION);
      extra_info.push_back(
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_1));
      extra_info.push_back(
          l10n_util::GetStringUTF16(
              IDS_CERT_ERROR_WEAK_KEY_EXTRA_INFO_2));
      break;
    case UNKNOWN:
      title = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE);
      details = l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS);
      short_description =
          l10n_util::GetStringUTF16(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
      break;
    default:
      NOTREACHED();
  }
  return SSLErrorInfo(title, details, short_description, extra_info);
}


   PowerPopupView() {
     SetHorizontalAlignment(ALIGN_RIGHT);
     UpdateText();
   }

Use-after-free vulnerability in Google Chrome before 20.0.1132.57 allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to counter handling.


   PowerPopupView() {
     SetHorizontalAlignment(ALIGN_RIGHT);
    SetMultiLine(true);
     UpdateText();
   }


  virtual void SetUpCommandLine(CommandLine* command_line) {
    GpuFeatureTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kEnableThreadedCompositing);
  }

Use-after-free vulnerability in Google Chrome before 20.0.1132.43 allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to SVG resources.


  virtual void SetUpCommandLine(CommandLine* command_line) {
    GpuFeatureTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
  }


bool GraphicsContext3D::getImageData(Image* image,
                                     GC3Denum format,
                                     GC3Denum type,
                                     bool premultiplyAlpha,
                                     bool ignoreGammaAndColorProfile,
                                     Vector<uint8_t>& outputVector)
{
    if (!image)
         return false;
     CGImageRef cgImage;
     RetainPtr<CGImageRef> decodedImage;
    bool hasAlpha = image->isBitmapImage() ? static_cast<BitmapImage*>(image)->frameHasAlphaAtIndex(0) : true;
     if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
         ImageSource decoder(ImageSource::AlphaNotPremultiplied,
                             ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
        decoder.setData(image->data(), true);
        if (!decoder.frameCount())
            return false;
        decodedImage.adoptCF(decoder.createFrameAtIndex(0));
        cgImage = decodedImage.get();
    } else
        cgImage = image->nativeImageForCurrentFrame();
    if (!cgImage)
        return false;

    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    if (!width || !height)
        return false;

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
    CGColorSpaceModel model = CGColorSpaceGetModel(colorSpace);
    if (model == kCGColorSpaceModelIndexed) {
        RetainPtr<CGContextRef> bitmapContext;
        bitmapContext.adoptCF(CGBitmapContextCreate(0, width, height, 8, width * 4,
                                                    deviceRGBColorSpaceRef(),
                                                    kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
        if (!bitmapContext)
            return false;

        CGContextSetBlendMode(bitmapContext.get(), kCGBlendModeCopy);
        CGContextSetInterpolationQuality(bitmapContext.get(), kCGInterpolationNone);
        CGContextDrawImage(bitmapContext.get(), CGRectMake(0, 0, width, height), cgImage);

        decodedImage.adoptCF(CGBitmapContextCreateImage(bitmapContext.get()));
        cgImage = decodedImage.get();
    }

    size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
    if (bitsPerComponent != 8 && bitsPerComponent != 16)
        return false;
    if (bitsPerPixel % bitsPerComponent)
        return false;
    size_t componentsPerPixel = bitsPerPixel / bitsPerComponent;

    CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage);
    bool bigEndianSource = false;
    if (bitsPerComponent == 16) {
        switch (bitInfo & kCGBitmapByteOrderMask) {
        case kCGBitmapByteOrder16Big:
            bigEndianSource = true;
            break;
        case kCGBitmapByteOrder16Little:
            bigEndianSource = false;
            break;
        case kCGBitmapByteOrderDefault:
            bigEndianSource = true;
            break;
        default:
            return false;
        }
    } else {
        switch (bitInfo & kCGBitmapByteOrderMask) {
        case kCGBitmapByteOrder32Big:
            bigEndianSource = true;
            break;
        case kCGBitmapByteOrder32Little:
            bigEndianSource = false;
            break;
        case kCGBitmapByteOrderDefault:
            bigEndianSource = true;
            break;
        default:
            return false;
        }
    }

    AlphaOp neededAlphaOp = AlphaDoNothing;
    AlphaFormat alphaFormat = AlphaFormatNone;
    switch (CGImageGetAlphaInfo(cgImage)) {
    case kCGImageAlphaPremultipliedFirst:
        if (!premultiplyAlpha)
            neededAlphaOp = AlphaDoUnmultiply;
        alphaFormat = AlphaFormatFirst;
        break;
    case kCGImageAlphaFirst:
        if (premultiplyAlpha)
            neededAlphaOp = AlphaDoPremultiply;
        alphaFormat = AlphaFormatFirst;
        break;
    case kCGImageAlphaNoneSkipFirst:
        alphaFormat = AlphaFormatFirst;
        break;
    case kCGImageAlphaPremultipliedLast:
        if (!premultiplyAlpha)
            neededAlphaOp = AlphaDoUnmultiply;
        alphaFormat = AlphaFormatLast;
        break;
    case kCGImageAlphaLast:
        if (premultiplyAlpha)
            neededAlphaOp = AlphaDoPremultiply;
        alphaFormat = AlphaFormatLast;
        break;
    case kCGImageAlphaNoneSkipLast:
        alphaFormat = AlphaFormatLast;
        break;
    case kCGImageAlphaNone:
        alphaFormat = AlphaFormatNone;
        break;
    default:
        return false;
    }
    SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, bigEndianSource);
    if (srcDataFormat == SourceFormatNumFormats)
        return false;

    RetainPtr<CFDataRef> pixelData;
    pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage)));
    if (!pixelData)
        return false;
    const UInt8* rgba = CFDataGetBytePtr(pixelData.get());

    unsigned int packedSize;
    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
        return false;
    outputVector.resize(packedSize);

    unsigned int srcUnpackAlignment = 0;
    size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
    unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width;
    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }
    bool rt = packPixels(rgba, srcDataFormat, width, height, srcUnpackAlignment,
                         format, type, neededAlphaOp, outputVector.data());
    return rt;
}

Use-after-free vulnerability in Google Chrome before 20.0.1132.43 allows remote attackers to cause a denial of service or possibly have unspecified other impact via vectors related to SVG painting.