Commit message: None
CVE: CVE-2016-5191
CWE: CWE-79
Vulnerability description: Bookmark handling in Google Chrome prior to 54.0.2840.59 for Windows, Mac, and Linux; 54.0.2840.85 for Android had insufficient validation of supplied data, which allowed a remote attacker to inject arbitrary scripts or HTML (UXSS) via crafted HTML pages, as demonstrated by an interpretation conflict between userinfo and scheme in an http://javascript:payload@example.com URL.

Project: Chrome

int GetBookmarkDragOperation(content::BrowserContext* browser_context,
                             const BookmarkNode* node) {
  PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
  BookmarkModel* model =
      BookmarkModelFactory::GetForBrowserContext(browser_context);

  int move = ui::DragDropTypes::DRAG_MOVE;
  if (!prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled) ||
      !model->client()->CanBeEditedByUser(node)) {
    move = ui::DragDropTypes::DRAG_NONE;
  }
  if (node->is_url())
    return ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK | move;
  return ui::DragDropTypes::DRAG_COPY | move;
}

Project: Chrome

int GetBookmarkDropOperation(Profile* profile,
                             const ui::DropTargetEvent& event,
                             const bookmarks::BookmarkNodeData& data,
                             const BookmarkNode* parent,
                             int index) {
  const base::FilePath& profile_path = profile->GetPath();

  if (data.IsFromProfilePath(profile_path) && data.size() > 1)
    return ui::DragDropTypes::DRAG_NONE;

  if (!IsValidBookmarkDropLocation(profile, data, parent, index))
    return ui::DragDropTypes::DRAG_NONE;

  BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile);
  if (!model->client()->CanBeEditedByUser(parent))
    return ui::DragDropTypes::DRAG_NONE;

  const BookmarkNode* dragged_node =
      data.GetFirstNode(model, profile->GetPath());
  if (dragged_node) {
    if (!model->client()->CanBeEditedByUser(dragged_node)) {
      return ui::DragDropTypes::DRAG_COPY;
    }
    return ui::DragDropTypes::DRAG_MOVE;
  }

  return GetPreferredBookmarkDropOperation(event.source_operations(),
      ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK);
}

Project: Chrome

gfx::ImageSkia GetBookmarkManagedFolderIcon(SkColor text_color) {
#if defined(OS_WIN)
  return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
      IDR_BOOKMARK_BAR_FOLDER_MANAGED);
#else
  return GetFolderIcon(gfx::VectorIconId::FOLDER_MANAGED, text_color);
#endif
}

Project: Chrome

gfx::ImageSkia GetBookmarkSupervisedFolderIcon(SkColor text_color) {
#if defined(OS_WIN)
  return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
      IDR_BOOKMARK_BAR_FOLDER_SUPERVISED);
#else
  return GetFolderIcon(gfx::VectorIconId::FOLDER_SUPERVISED, text_color);
#endif
}

Project: Chrome

gfx::ImageSkia GetFolderIcon(gfx::VectorIconId id, SkColor text_color) {
  return gfx::CreateVectorIcon(id,
                               color_utils::DeriveDefaultIconColor(text_color));
}

Project: Chrome

void GetURLAndTitleToBookmark(content::WebContents* web_contents,
                              GURL* url,
                              base::string16* title) {
  *url = GetURLToBookmark(web_contents);
  *title = web_contents->GetTitle();
}

Project: Chrome

GURL GetURLToBookmark(content::WebContents* web_contents) {
  DCHECK(web_contents);
  return search::IsInstantNTP(web_contents) ? GURL(kChromeUINewTabURL)
                                            : web_contents->GetURL();
}

Project: Chrome

 bool IsAppsShortcutEnabled(Profile* profile) {
  if (profile->IsLegacySupervised())
    return false;

#if defined(USE_ASH)
  return false;
#else
  return search::IsInstantExtendedAPIEnabled() && !profile->IsOffTheRecord();
#endif
}

Project: Chrome

bool IsValidBookmarkDropLocation(Profile* profile,
                                 const bookmarks::BookmarkNodeData& data,
                                 const BookmarkNode* drop_parent,
                                 int index) {
  if (!drop_parent->is_folder()) {
    NOTREACHED();
    return false;
  }

  if (!data.is_valid())
    return false;

  BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile);
  if (!model->client()->CanBeEditedByUser(drop_parent))
    return false;

  const base::FilePath& profile_path = profile->GetPath();
  if (data.IsFromProfilePath(profile_path)) {
    std::vector<const BookmarkNode*> nodes = data.GetNodes(model, profile_path);
    for (size_t i = 0; i < nodes.size(); ++i) {
      const BookmarkNode* node = nodes[i];
      int node_index = (drop_parent == node->parent()) ?
          drop_parent->GetIndexOf(nodes[i]) : -1;
      if (node_index != -1 && (index == node_index || index == node_index + 1))
        return false;

      if (drop_parent->HasAncestor(node))
        return false;
    }
    return true;
  }
  return true;
}

Project: Chrome

bool ShouldRemoveBookmarkOpenPagesUI(Profile* profile) {
#if defined(ENABLE_EXTENSIONS)
  extensions::ExtensionRegistry* registry =
      extensions::ExtensionRegistry::Get(profile);
  if (!registry)
    return false;

  const extensions::ExtensionSet& extension_set =
      registry->enabled_extensions();

  for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
       i != extension_set.end();
       ++i) {
    if (extensions::CommandService::RemovesBookmarkOpenPagesShortcut(i->get()))
      return true;
  }
#endif

  return false;
}

Project: Chrome

bool ShouldRemoveBookmarkThisPageUI(Profile* profile) {
  return GetBookmarkShortcutDisposition(profile) ==
         BOOKMARK_SHORTCUT_DISPOSITION_REMOVED;
}

Project: Chrome

bool ShouldShowAppsShortcutInBookmarkBar(Profile* profile) {
  return IsAppsShortcutEnabled(profile) &&
         profile->GetPrefs()->GetBoolean(
             bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
}

Project: Chrome

void ToggleBookmarkBarWhenVisible(content::BrowserContext* browser_context) {
  PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
  const bool always_show =
      !prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar);

  prefs->SetBoolean(bookmarks::prefs::kShowBookmarkBar, always_show);
}

Project: Chrome

  void AddTestData() {
    const BookmarkNode* bb_node = model_->bookmark_bar_node();
    std::string test_base = base_path();
    model_->AddURL(bb_node, 0, ASCIIToUTF16("a"), GURL(test_base + "a"));
    const BookmarkNode* f1 = model_->AddFolder(bb_node, 1, ASCIIToUTF16("F1"));
    model_->AddURL(f1, 0, ASCIIToUTF16("f1a"), GURL(test_base + "f1a"));
    const BookmarkNode* f11 = model_->AddFolder(f1, 1, ASCIIToUTF16("F11"));
    model_->AddURL(f11, 0, ASCIIToUTF16("f11a"), GURL(test_base + "f11a"));
    model_->AddFolder(bb_node, 2, ASCIIToUTF16("F2"));

    model_->AddURL(model_->other_node(), 0, ASCIIToUTF16("oa"),
                   GURL(test_base + "oa"));
    const BookmarkNode* of1 =
        model_->AddFolder(model_->other_node(), 1, ASCIIToUTF16("OF1"));
    model_->AddURL(of1, 0, ASCIIToUTF16("of1a"), GURL(test_base + "of1a"));
  }

Project: Chrome

   void ApplyEdits() {
     editor_->ApplyEdits();
   }

Project: Chrome

  BookmarkEditorViewTest() : model_(nullptr) {}

Project: Chrome

  void CreateEditor(Profile* profile,
                    const BookmarkNode* parent,
                    const BookmarkEditor::EditDetails& details,
                    BookmarkEditor::Configuration configuration) {
    editor_.reset(new BookmarkEditorView(profile, parent, details,
                                         configuration));
  }

Project: Chrome

  void ExpandAndSelect() {
    editor_->ExpandAndSelect();
  }

Project: Chrome

  BookmarkNode* GetMutableNode(const std::string& name) {
    return const_cast<BookmarkNode*>(GetNode(name));
  }

Project: Chrome

  void NewFolder() {
    return editor_->NewFolder();
  }

Project: Chrome

  void SetTitleText(const base::string16& title) {
    editor_->title_tf_->SetText(title);
  }

Project: Chrome

  void SetURLText(const base::string16& text) {
    if (editor_->details_.type != BookmarkEditor::EditDetails::NEW_FOLDER)
       editor_->url_tf_->SetText(text);
   }

Project: Chrome

  bool URLTFHasParent() {
    if (editor_->details_.type == BookmarkEditor::EditDetails::NEW_FOLDER)
      return false;
    return editor_->url_tf_->parent();
  }

Project: Chrome

  std::string base_path() const { return "file:///c:/tmp/"; }

Project: Chrome

  BookmarkEditorView::EditorTreeModel* editor_tree_model() {
    return editor_->tree_model_.get();
  }