Commit f13db814 authored by huangs's avatar huangs Committed by Commit bot

[Icons NTP] Allow chrome-search:// large-icon and fallback-icon hosts to use...

[Icons NTP] Allow chrome-search:// large-icon and fallback-icon hosts to use <view_id>/<restricted_id> instead of URL.

For chrome-search://thumbnail on NTP we don't allow direct URL queries,
but only allow <view_id>/<restricted_id>. We're adding the same features
to chrome-search://big-icon and chrome-search://fallback-icon . For the
latter we can actually enable both direct URL and ID's (since URL is only
parsed to extract first letter in domain name) -- but we don't need this
feature right now.

BUG=467712

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

Cr-Commit-Position: refs/heads/master@{#321638}
parent bbac0e74
......@@ -1366,10 +1366,17 @@ bool ChromeContentRendererClient::WillSendRequest(
content::RenderView::FromWebView(frame->view());
SearchBox* search_box = SearchBox::Get(render_view);
if (search_box && url.SchemeIs(chrome::kChromeSearchScheme)) {
if (url.host() == chrome::kChromeUIThumbnailHost)
return search_box->GenerateThumbnailURLFromTransientURL(url, new_url);
else if (url.host() == chrome::kChromeUIFaviconHost)
return search_box->GenerateFaviconURLFromTransientURL(url, new_url);
SearchBox::ImageSourceType type = SearchBox::NONE;
if (url.host() == chrome::kChromeUIFaviconHost)
type = SearchBox::FAVICON;
else if (url.host() == chrome::kChromeUILargeIconHost)
type = SearchBox::LARGE_ICON;
else if (url.host() == chrome::kChromeUIFallbackIconHost)
type = SearchBox::FALLBACK_ICON;
else if (url.host() == chrome::kChromeUIThumbnailHost)
type = SearchBox::THUMB;
if (type != SearchBox::NONE)
return search_box->GenerateImageURLFromTransientURL(url, type, new_url);
}
return false;
......
......@@ -6,12 +6,15 @@
#include <string>
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/favicon/fallback_icon_url_parser.h"
#include "chrome/common/favicon/favicon_url_parser.h"
#include "chrome/common/favicon/large_icon_url_parser.h"
#include "chrome/common/omnibox_focus_state.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
......@@ -49,99 +52,180 @@ bool AreMostVisitedItemsEqual(
return true;
}
const char* GetIconTypeUrlHost(SearchBox::ImageSourceType type) {
switch (type) {
case SearchBox::FAVICON:
return "favicon";
case SearchBox::LARGE_ICON:
return "large-icon";
case SearchBox::FALLBACK_ICON:
return "fallback-icon";
case SearchBox::THUMB:
return "thumb";
default:
NOTREACHED();
}
return nullptr;
}
// Given |path| from an image URL, returns starting index of the page URL,
// depending on |type| of image URL. Returns -1 if parse fails.
int GetImagePathStartOfPageURL(SearchBox::ImageSourceType type,
const std::string& path) {
// TODO(huangs): Refactor this: http://crbug.com/468320.
switch (type) {
case SearchBox::FAVICON: {
chrome::ParsedFaviconPath parsed;
return chrome::ParseFaviconPath(
path, favicon_base::FAVICON, &parsed) ? parsed.path_index : -1;
}
case SearchBox::LARGE_ICON: {
LargeIconUrlParser parser;
return parser.Parse(path) ? parser.path_index() : -1;
}
case SearchBox::FALLBACK_ICON: {
chrome::ParsedFallbackIconPath parser;
return parser.Parse(path) ? parser.path_index() : -1;
}
case SearchBox::THUMB: {
return 0;
}
default: {
NOTREACHED();
break;
}
}
return -1;
}
// Helper for SearchBox::GenerateImageURLFromTransientURL().
class SearchBoxIconURLHelper: public SearchBox::IconURLHelper {
public:
explicit SearchBoxIconURLHelper(const SearchBox* search_box);
~SearchBoxIconURLHelper() override;
int GetViewID() const override;
std::string GetURLStringFromRestrictedID(InstantRestrictedID rid) const
override;
private:
const SearchBox* search_box_;
};
SearchBoxIconURLHelper::SearchBoxIconURLHelper(const SearchBox* search_box)
: search_box_(search_box) {
}
SearchBoxIconURLHelper::~SearchBoxIconURLHelper() {
}
int SearchBoxIconURLHelper::GetViewID() const {
return search_box_->render_view()->GetRoutingID();
}
std::string SearchBoxIconURLHelper::GetURLStringFromRestrictedID(
InstantRestrictedID rid) const {
InstantMostVisitedItem item;
if (!search_box_->GetMostVisitedItemWithID(rid, &item))
return std::string();
return item.url.spec();
}
} // namespace
namespace internal { // for testing
// Parses |path| and fills in |id| with the InstantRestrictedID obtained from
// the |path|. |render_view_id| is the ID of the associated RenderView.
//
// |path| is a pair of |render_view_id| and |restricted_id|, and it is
// contained in Instant Extended URLs. A valid |path| is in the form:
// <render_view_id>/<restricted_id>
//
// If the |path| is valid, returns true and fills in |id| with restricted_id
// value. If the |path| is invalid, returns false and |id| is not set.
bool GetInstantRestrictedIDFromPath(int render_view_id,
const std::string& path,
InstantRestrictedID* id) {
// Parses "<view_id>/<restricted_id>". If successful, assigns
// |*view_id| := "<view_id>", |*rid| := "<restricted_id>", and returns true.
bool ParseViewIdAndRestrictedId(const std::string id_part,
int* view_id_out,
InstantRestrictedID* rid_out) {
DCHECK(view_id_out);
DCHECK(rid_out);
// Check that the path is of Most visited item ID form.
std::vector<std::string> tokens;
if (Tokenize(path, "/", &tokens) != 2)
if (Tokenize(id_part, "/", &tokens) != 2)
return false;
int view_id = 0;
if (!base::StringToInt(tokens[0], &view_id) || view_id != render_view_id)
int view_id;
InstantRestrictedID rid;
if (!base::StringToInt(tokens[0], &view_id) || view_id < 0 ||
!base::StringToInt(tokens[1], &rid) || rid < 0)
return false;
return base::StringToInt(tokens[1], id);
*view_id_out = view_id;
*rid_out = rid;
return true;
}
bool GetRestrictedIDFromFaviconUrl(int render_view_id,
const GURL& url,
std::string* favicon_params,
InstantRestrictedID* rid) {
// Takes icon |url| of given |type|, e.g., FAVICON looking like
//
// chrome-search://favicon/<view_id>/<restricted_id>
// chrome-search://favicon/<parameters>/<view_id>/<restricted_id>
//
// If successful, assigns |*param_part| := "" or "<parameters>/" (note trailing
// slash), |*view_id| := "<view_id>", |*rid| := "rid", and returns true.
bool ParseIconRestrictedUrl(const GURL& url,
SearchBox::ImageSourceType type,
std::string* param_part,
int* view_id,
InstantRestrictedID* rid) {
DCHECK(param_part);
DCHECK(view_id);
DCHECK(rid);
// Strip leading slash.
std::string raw_path = url.path();
DCHECK_GT(raw_path.length(), (size_t) 0);
DCHECK_EQ(raw_path[0], '/');
raw_path = raw_path.substr(1);
chrome::ParsedFaviconPath parsed;
if (!chrome::ParseFaviconPath(raw_path, favicon_base::FAVICON, &parsed))
int path_index = GetImagePathStartOfPageURL(type, raw_path);
if (path_index < 0)
return false;
std::string id_part = raw_path.substr(path_index);
if (!ParseViewIdAndRestrictedId(id_part, view_id, rid))
return false;
// The part of the URL which details the favicon parameters should be returned
// so the favicon URL can be reconstructed, by replacing the restricted_id
// with the actual URL from which the favicon is being requested.
*favicon_params = raw_path.substr(0, parsed.path_index);
// The part of the favicon URL which is supposed to contain the URL from
// which the favicon is being requested (i.e., the page's URL) actually
// contains a pair in the format "<view_id>/<restricted_id>". If the page's
// URL is not in the expected format then the execution must be stopped,
// returning |true|, indicating that the favicon URL should be translated
// without the page's URL part, to prevent search providers from spoofing
// the user's browsing history. For example, the following favicon URL
// "chrome-search://favicon/http://www.secretsite.com" it is not in the
// expected format "chrome-search://favicon/<view_id>/<restricted_id>" so
// the pages's URL part ("http://www.secretsite.com") should be removed
// entirely from the translated URL otherwise the search engine would know
// if the user has visited that page (by verifying whether the favicon URL
// returns an image for a particular page's URL); the translated URL in this
// case would be "chrome-search://favicon/" which would simply return the
// default favicon.
std::string id_part = raw_path.substr(parsed.path_index);
InstantRestrictedID id;
if (!GetInstantRestrictedIDFromPath(render_view_id, id_part, &id))
return true;
*rid = id;
*param_part = raw_path.substr(0, path_index);
return true;
}
// Parses a thumbnail |url| and fills in |id| with the InstantRestrictedID
// obtained from the |url|. |render_view_id| is the ID of the associated
// RenderView.
//
// Valid |url| forms:
// chrome-search://thumb/<view_id>/<restricted_id>
//
// If the |url| is valid, returns true and fills in |id| with restricted_id
// value. If the |url| is invalid, returns false and |id| is not set.
bool GetRestrictedIDFromThumbnailUrl(int render_view_id,
const GURL& url,
InstantRestrictedID* id) {
// Strip leading slash.
std::string path = url.path();
DCHECK_GT(path.length(), (size_t) 0);
DCHECK_EQ(path[0], '/');
path = path.substr(1);
bool TranslateIconRestrictedUrl(const GURL& transient_url,
SearchBox::ImageSourceType type,
const SearchBox::IconURLHelper& helper,
GURL* url) {
std::string params;
int view_id = -1;
InstantRestrictedID rid = -1;
if (!internal::ParseIconRestrictedUrl(
transient_url, type, &params, &view_id, &rid) ||
view_id != helper.GetViewID()) {
if (type == SearchBox::FAVICON) {
*url = GURL(base::StringPrintf("chrome-search://%s/",
GetIconTypeUrlHost(SearchBox::FAVICON)));
return true;
}
return false;
}
return GetInstantRestrictedIDFromPath(render_view_id, path, id);
std::string item_url = helper.GetURLStringFromRestrictedID(rid);
*url = GURL(base::StringPrintf("chrome-search://%s/%s%s",
GetIconTypeUrlHost(type),
params.c_str(),
item_url.c_str()));
return true;
}
} // namespace internal
SearchBox::IconURLHelper::IconURLHelper() {
}
SearchBox::IconURLHelper::~IconURLHelper() {
}
SearchBox::SearchBox(content::RenderView* render_view)
: content::RenderViewObserver(render_view),
content::RenderViewObserverTracker<SearchBox>(render_view),
......@@ -201,40 +285,11 @@ void SearchBox::DeleteMostVisitedItem(
GetURLForMostVisitedItem(most_visited_item_id)));
}
bool SearchBox::GenerateFaviconURLFromTransientURL(const GURL& transient_url,
GURL* url) const {
std::string favicon_params;
InstantRestrictedID rid = -1;
bool success = internal::GetRestrictedIDFromFaviconUrl(
render_view()->GetRoutingID(), transient_url, &favicon_params, &rid);
if (!success)
return false;
InstantMostVisitedItem item;
std::string item_url;
if (rid != -1 && GetMostVisitedItemWithID(rid, &item))
item_url = item.url.spec();
*url = GURL(base::StringPrintf("chrome-search://favicon/%s%s",
favicon_params.c_str(),
item_url.c_str()));
return true;
}
bool SearchBox::GenerateThumbnailURLFromTransientURL(const GURL& transient_url,
GURL* url) const {
InstantRestrictedID rid = 0;
if (!internal::GetRestrictedIDFromThumbnailUrl(render_view()->GetRoutingID(),
transient_url, &rid)) {
return false;
}
GURL most_visited_item_url(GetURLForMostVisitedItem(rid));
if (most_visited_item_url.is_empty())
return false;
*url = GURL(base::StringPrintf("chrome-search://thumb/%s",
most_visited_item_url.spec().c_str()));
return true;
bool SearchBox::GenerateImageURLFromTransientURL(const GURL& transient_url,
ImageSourceType type,
GURL* url) const {
SearchBoxIconURLHelper helper(this);
return internal::TranslateIconRestrictedUrl(transient_url, type, helper, url);
}
void SearchBox::GetMostVisitedItems(
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_
#define CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
......@@ -25,6 +26,27 @@ class RenderView;
class SearchBox : public content::RenderViewObserver,
public content::RenderViewObserverTracker<SearchBox> {
public:
enum ImageSourceType {
NONE = -1,
FAVICON,
LARGE_ICON,
FALLBACK_ICON,
THUMB
};
// Helper class for GenerateImageURLFromTransientURL() to adapt SearchBox's
// instance, thereby allow mocking for unit tests.
class IconURLHelper {
public:
IconURLHelper();
virtual ~IconURLHelper();
// Retruns view id for validating icon URL.
virtual int GetViewID() const = 0;
// Returns the page URL string for |rid|, or empty string for invalid |rid|.
virtual std::string GetURLStringFromRestrictedID(InstantRestrictedID rid)
const = 0;
};
explicit SearchBox(content::RenderView* render_view);
~SearchBox() override;
......@@ -46,27 +68,35 @@ class SearchBox : public content::RenderViewObserver,
// Sends ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem to the browser.
void DeleteMostVisitedItem(InstantRestrictedID most_visited_item_id);
// Generates the favicon URL of the most visited item specified by the
// |transient_url|. If the |transient_url| is valid, returns true and fills in
// |url|. If the |transient_url| is invalid, returns true and |url| is set to
// "chrome-search://favicon/" in order to prevent the invalid URL to be
// requested.
// Generates the image URL of |type| for the most visited item specified in
// |transient_url|. If |transient_url| is valid, |url| with a translated URL
// and returns true. Otherwise it depends on |type|:
// - FAVICON: Returns true and renders an URL to display the default favicon.
// - LARGE_ICON and FALLBACK_ICON: Returns false.
//
// Valid forms of |transient_url|:
// For |type| == FAVICON, valid forms of |transient_url|:
// chrome-search://favicon/<view_id>/<restricted_id>
// chrome-search://favicon/<favicon_parameters>/<view_id>/<restricted_id>
bool GenerateFaviconURLFromTransientURL(const GURL& transient_url,
GURL* url) const;
// Generates the thumbnail URL of the most visited item specified by the
// |transient_url|. If the |transient_url| is valid, returns true and fills in
// |url|. If the |transient_url| is invalid, returns false and |url| is not
// set.
//
// Valid form of |transient_url|:
// For |type| == LARGE_ICON, valid form of |transient_url|:
// chrome-search://large-icon/<size>/<view_id>/<restricted_id>
//
// For |type| == FALLBACK_ICON, valid form of |transient_url|:
// chrome-search://fallback-icon/<icon specs>/<view_id>/<restricted_id>
//
// For |type| == THUMB, valid form of |transient_url|:
// chrome-search://thumb/<render_view_id>/<most_visited_item_id>
bool GenerateThumbnailURLFromTransientURL(const GURL& transient_url,
GURL* url) const;
//
// We do this to prevent search providers from abusing image URLs and deduce
// whether the user has visited a particular page. For example, if
// "chrome-search://favicon/http://www.secretsite.com" is accessible, then
// the search provider can use its return code to determine whether the user
// has visited "http://www.secretsite.com". Therefore we require search
// providers to specify URL by "<view_id>/<restricted_id>". We then translate
// this to the original |url|, and pass the request to the proper endpoint.
bool GenerateImageURLFromTransientURL(const GURL& transient_url,
ImageSourceType type,
GURL* url) const;
// Returns the latest most visited items sent by the browser.
void GetMostVisitedItems(
......
......@@ -2,231 +2,323 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/searchbox/searchbox.h"
#include <map>
#include <string>
#include "base/basictypes.h"
#include "chrome/common/instant_types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace {
const auto FAVICON = SearchBox::FAVICON;
const auto LARGE_ICON = SearchBox::LARGE_ICON;
const auto FALLBACK_ICON = SearchBox::FALLBACK_ICON;
const auto THUMB = SearchBox::THUMB;
const char* kUrlString1 = "http://www.google.com";
const char* kUrlString2 = "http://www.chromium.org/path/q=3#r=4";
const char* kUrlString3 = "http://www.youtube.com:8080/hosps";
// Mock helper to test internal::TranslateIconRestrictedUrl().
class MockIconURLHelper: public SearchBox::IconURLHelper {
public:
MockIconURLHelper();
~MockIconURLHelper() override;
int GetViewID() const override;
std::string GetURLStringFromRestrictedID(InstantRestrictedID rid) const
override;
private:
std::map<InstantRestrictedID, std::string> rid_to_url_string_;
};
MockIconURLHelper::MockIconURLHelper() {
rid_to_url_string_[1] = kUrlString1;
rid_to_url_string_[2] = kUrlString2;
rid_to_url_string_[3] = kUrlString3;
}
MockIconURLHelper::~MockIconURLHelper() {
}
int MockIconURLHelper::GetViewID() const {
return 137;
}
std::string MockIconURLHelper::GetURLStringFromRestrictedID(
InstantRestrictedID rid) const {
auto it = rid_to_url_string_.find(rid);
return it == rid_to_url_string_.end() ? std::string() : it->second;
}
} // namespace
namespace internal {
// Defined in searchbox.cc
bool GetRestrictedIDFromThumbnailUrl(int render_view_id,
const GURL& url,
InstantRestrictedID* id);
bool ParseViewIdAndRestrictedId(const std::string id_part,
int* view_id_out,
InstantRestrictedID* rid_out);
// Defined in searchbox.cc
bool ParseIconRestrictedUrl(const GURL& url,
SearchBox::ImageSourceType type,
std::string* param_part,
int* view_id,
InstantRestrictedID* rid);
// Defined in searchbox.cc
bool GetRestrictedIDFromFaviconUrl(int render_view_id,
const GURL& url,
std::string* favicon_params,
InstantRestrictedID* rid);
TEST(SearchBoxUtilTest, GetInstantRestrictedIDFromTransientURL) {
const int kInvalidRenderViewID = 920;
const int kValidRenderViewID = 1;
const struct {
int render_view_id;
GURL transient_url;
bool TranslateIconRestrictedUrl(const GURL& transient_url,
SearchBox::ImageSourceType type,
const SearchBox::IconURLHelper& helper,
GURL* url);
TEST(SearchBoxUtilTest, ParseViewIdAndRestrictedIdSuccess) {
int view_id = -1;
InstantRestrictedID rid = -1;
EXPECT_TRUE(ParseViewIdAndRestrictedId("2/3", &view_id, &rid));
EXPECT_EQ(2, view_id);
EXPECT_EQ(3, rid);
EXPECT_TRUE(ParseViewIdAndRestrictedId("0/0", &view_id, &rid));
EXPECT_EQ(0, view_id);
EXPECT_EQ(0, rid);
EXPECT_TRUE(ParseViewIdAndRestrictedId("1048576/314", &view_id, &rid));
EXPECT_EQ(1048576, view_id);
EXPECT_EQ(314, rid);
// Odd but not fatal.
EXPECT_TRUE(ParseViewIdAndRestrictedId("00/09", &view_id, &rid));
EXPECT_EQ(0, view_id);
EXPECT_EQ(9, rid);
// Tolerates multiple, leading, and trailing "/".
EXPECT_TRUE(ParseViewIdAndRestrictedId("2////3", &view_id, &rid));
EXPECT_EQ(2, view_id);
EXPECT_EQ(3, rid);
EXPECT_TRUE(ParseViewIdAndRestrictedId("5/6/", &view_id, &rid));
EXPECT_EQ(5, view_id);
EXPECT_EQ(6, rid);
EXPECT_TRUE(ParseViewIdAndRestrictedId("/7/8", &view_id, &rid));
EXPECT_EQ(7, view_id);
EXPECT_EQ(8, rid);
}
TEST(SearchBoxUtilTest, ParseViewIdAndRestrictedIdFailure) {
const char* test_cases[] = {
"",
" ",
"/",
"2/",
"/3",
"2a/3",
"2/3a",
" 2/3",
"2/ 3",
"2 /3 ",
"23",
"2,3",
"-2/3",
"2/-3",
"2/3/1",
"blahblah",
"0xA/0x10",
};
for (size_t i = 0; i < arraysize(test_cases); ++i) {
int view_id = -1;
InstantRestrictedID rid = -1;
EXPECT_FALSE(ParseViewIdAndRestrictedId(test_cases[i], &view_id, &rid))
<< " for test_cases[" << i << "]";
EXPECT_EQ(-1, view_id);
EXPECT_EQ(-1, rid);
}
}
TEST(SearchBoxUtilTest, ParseIconRestrictedUrlFaviconSuccess) {
struct {
SearchBox::ImageSourceType type;
const char* transient_url_str;
const char* expected_param_part;
int expected_view_id;
InstantRestrictedID expected_rid;
bool expected_return_val;
} test_cases[] = {
// RenderView ID matches the view id specified in the transient url.
{kValidRenderViewID, GURL("chrome-search://favicon/1/2"), 2, true},
{kValidRenderViewID, GURL("chrome-search://thumb/1/2"), 2, true},
// RenderView ID does not match the view id specified in the transient url.
{kInvalidRenderViewID, GURL("chrome-search://favicon/1/2"), 0, false},
{kInvalidRenderViewID, GURL("chrome-search://thumb/1/2"), 0, false},
// Invalid transient urls.
{kValidRenderViewID, GURL("chrome-search://thumb"), 0, false},
{kValidRenderViewID, GURL("chrome-search://thumb/"), 0, false},
{kValidRenderViewID, GURL("chrome-search://thumb/123"), 0, false},
{kValidRenderViewID, GURL("chrome-search://thumb/xyz"), 0, false},
{kValidRenderViewID, GURL("chrome-search://thumb/123/"), 0, false},
{kValidRenderViewID, GURL("chrome-search://thumb/123/xyz"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon/"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon/123"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon/xyz"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon/123/"), 0, false},
{kValidRenderViewID, GURL("chrome-search://favicon/123/xyz"), 0, false}
{FAVICON, "chrome-search://favicon/1/2", "", 1, 2},
{FAVICON, "chrome-search://favicon/size/16@2x/3/4", "size/16@2x/", 3, 4},
{FAVICON, "chrome-search://favicon/largest/5/6", "largest/", 5, 6},
{FAVICON, "chrome-search://favicon/origin/7/8", "origin/", 7, 8},
{FAVICON, "chrome-search://favicon/iconurl/9/10", "iconurl/", 9, 10},
{LARGE_ICON, "chrome-search://large-icon/96/1/2", "96/", 1, 2},
{LARGE_ICON, "chrome-search://large-icon/1/3/4", "1/", 3, 4},
// Size restriction is *not* enforced during parsing, but later.
{LARGE_ICON, "chrome-search://large-icon/1000000/5/6", "1000000/", 5, 6},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/1/2", ",,,,/", 1, 2},
{FALLBACK_ICON, "chrome-search://fallback-icon/1,,,,/3/4", "1,,,,/", 3, 4},
{FALLBACK_ICON, "chrome-search://fallback-icon/64,fff,black,0.4,0.6/5/6",
"64,fff,black,0.4,0.6/", 5, 6},
{THUMB, "chrome-search://thumb/1/2", "", 1, 2},
};
for (size_t i = 0; i < arraysize(test_cases); ++i) {
std::string param_part = "(unwritten)";
int view_id = -1;
InstantRestrictedID rid = -1;
EXPECT_TRUE(ParseIconRestrictedUrl(GURL(test_cases[i].transient_url_str),
test_cases[i].type, &param_part, &view_id, &rid))
<< " for test_cases[" << i << "]";
EXPECT_EQ(test_cases[i].expected_param_part, param_part)
<< " for test_cases[" << i << "]";
EXPECT_EQ(test_cases[i].expected_view_id, view_id)
<< " for test_cases[" << i << "]";
EXPECT_EQ(test_cases[i].expected_rid, rid)
<< " for test_cases[" << i << "]";
}
}
InstantRestrictedID rid = 0;
TEST(SearchBoxUtilTest, ParseIconRestrictedUrlFailure) {
struct {
SearchBox::ImageSourceType type;
const char* transient_url_str;
} test_cases[] = {
{FAVICON, "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/3/"},
{FAVICON, "chrome-search://favicon/size/3/4"},
{FAVICON, "chrome-search://favicon/largest/http://www.google.com"},
{FAVICON, "chrome-search://favicon/size/16@2x/-1/10"},
{LARGE_ICON, "chrome-search://large-icon/"},
{LARGE_ICON, "chrome-search://large-icon/3"},
{LARGE_ICON, "chrome-search://large-icon/3/4"},
{LARGE_ICON, "chrome-search://large-icon/-1/3/4"},
{LARGE_ICON, "chrome-search://large-icon/0/3/4"},
{LARGE_ICON, "chrome-search://large-icon/64/http://www.google.com"},
{LARGE_ICON, "chrome-search://large-icon/bad-size/3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon/"},
{FALLBACK_ICON, "chrome-search://fallback-icon/3"},
{FALLBACK_ICON, "chrome-search://fallback-icon/3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon//3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,/3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon/bad-spec/3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon/-1,,,,/3/4"},
{FALLBACK_ICON, "chrome-search://fallback-icon/,junk,,,/3/4"},
// This case is a bit stringent. Since we always render fallback icons,
// search privider can't use this to probe user history. We'll consider
// relaxing the check if the need arises.
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/http://www.google.com"},
{THUMB, "chrome-search://thumb"},
{THUMB, "chrome-search://thumb/"},
{THUMB, "chrome-search://thumb/123"},
{THUMB, "chrome-search://thumb/xyz"},
{THUMB, "chrome-search://thumb/123/"},
{THUMB, "chrome-search://thumb/123/xyz"},
{THUMB, "chrome-search://thumb/http://www.google.com"},
};
for (size_t i = 0; i < arraysize(test_cases); ++i) {
bool return_val = GetRestrictedIDFromThumbnailUrl(
test_cases[i].render_view_id, test_cases[i].transient_url, &rid);
EXPECT_EQ(test_cases[i].expected_return_val, return_val);
EXPECT_EQ(test_cases[i].expected_rid, rid);
rid = 0;
std::string param_part = "(unwritten)";
int view_id = -1;
InstantRestrictedID rid = -1;
EXPECT_FALSE(ParseIconRestrictedUrl(GURL(test_cases[i].transient_url_str),
test_cases[i].type, &param_part, &view_id, &rid))
<< " for test_cases[" << i << "]";
EXPECT_EQ("(unwritten)", param_part);
EXPECT_EQ(-1, view_id);
EXPECT_EQ(-1, rid);
}
}
TEST(SearchBoxUtilTest, ParseRestrictedFaviconTransientUrl) {
const int kInvalidRenderViewID = 920;
const int kValidRenderViewID = 1;
TEST(SearchBoxUtilTest, TranslateIconRestrictedUrlSuccess) {
struct {
SearchBox::ImageSourceType type;
const char* transient_url_str;
std::string expected_url_str;
} test_cases[] = {
{FAVICON, "chrome-search://favicon/137/1",
std::string("chrome-search://favicon/") + kUrlString1},
// FAVICON is permission: invalid input just yields default endpoint.
{FAVICON, "chrome-search://favicon/", "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/314", "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/314/1", "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/137/255", "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/-3/-1", "chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/invalidstuff",
"chrome-search://favicon/"},
{FAVICON, "chrome-search://favicon/size/16@2x/http://www.google.com",
"chrome-search://favicon/"},
// Other types of icons.
{LARGE_ICON, "chrome-search://large-icon/64/137/2",
std::string("chrome-search://large-icon/64/") + kUrlString2},
{LARGE_ICON, "chrome-search://large-icon/1/137/1",
std::string("chrome-search://large-icon/1/") + kUrlString1},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/137/3",
std::string("chrome-search://fallback-icon/,,,,/") + kUrlString3},
{FALLBACK_ICON, "chrome-search://fallback-icon/64,fff,,,1/137/1",
std::string("chrome-search://fallback-icon/64,fff,,,1/") + kUrlString1},
{THUMB, "chrome-search://thumb/137/3",
std::string("chrome-search://thumb/") + kUrlString3},
};
const struct {
int render_view_id;
GURL transient_url;
std::string expected_favicon_params;
InstantRestrictedID expected_rid;
bool expected_return_val;
MockIconURLHelper helper;
for (size_t i = 0; i < arraysize(test_cases); ++i) {
GURL url;
GURL transient_url(test_cases[i].transient_url_str);
EXPECT_TRUE(TranslateIconRestrictedUrl(transient_url, test_cases[i].type,
helper, &url))
<< " for test_cases[" << i << "]";
EXPECT_EQ(GURL(test_cases[i].expected_url_str), url)
<< " for test_cases[" << i << "]";
}
}
// For Non-FAVICON only.
TEST(SearchBoxUtilTest, TranslateIconRestrictedUrlFailure) {
struct {
SearchBox::ImageSourceType type;
const char* transient_url_str;
} test_cases[] = {
// RenderView ID matches the view id specified in the transient url.
{
kValidRenderViewID,
GURL("chrome-search://favicon/1/2"),
"",
2,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/1/2"),
"size/16@2x/",
2,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/largest/1/2"),
"largest/",
2,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/origin/1/2"),
"origin/",
2,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/iconurl/1/2"),
"iconurl/",
2,
true
},
// RenderView ID does not match the view id specified in the transient url.
{
kInvalidRenderViewID,
GURL("chrome-search://favicon/1/2"),
"",
0,
true
},
{
kInvalidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/1/2"),
"size/16@2x/",
0,
true
},
{
kInvalidRenderViewID,
GURL("chrome-search://favicon/largest/1/2"),
"largest/",
0,
true
},
{
kInvalidRenderViewID,
GURL("chrome-search://favicon/origin/1/2"),
"origin/",
0,
true
},
{
kInvalidRenderViewID,
GURL("chrome-search://favicon/iconurl/1/2"),
"iconurl/",
0,
true
},
// Invalid transient urls.
{
kValidRenderViewID,
GURL("chrome-search://favicon"),
"",
0,
false
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/"),
"",
0,
false
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x"),
"",
0,
false
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size"),
"",
0,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/123"),
"size/16@2x/",
0,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/xyz"),
"size/16@2x/",
0,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/123/"),
"size/16@2x/",
0,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/size/16@2x/123/xyz"),
"size/16@2x/",
0,
true
},
{
kValidRenderViewID,
GURL("chrome-search://favicon/invalidparameter/16@2x/1/2"),
"",
0,
true
}
// Empty.
{LARGE_ICON, "chrome-search://large-icon/"},
{FALLBACK_ICON, "chrome-search://fallback-icon/"},
{THUMB, "chrome-search://thumb/"},
// Bad view_id.
{LARGE_ICON, "chrome-search://large-icon/64/314/2"},
{LARGE_ICON, "chrome-search://large-icon/1/314/1"},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/314/3"},
{FALLBACK_ICON, "chrome-search://fallback-icon/64,fff,,,1/314/1"},
{THUMB, "chrome-search://thumb/314/1"},
// Missing rid.
{LARGE_ICON, "chrome-search://large-icon/64/137/"},
{LARGE_ICON, "chrome-search://large-icon/64/137/blah"},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/137/"},
{THUMB, "chrome-search://thumb/314/"},
// Bad params.
{LARGE_ICON, "chrome-search://large-icon/137/2"},
{LARGE_ICON, "chrome-search://large-icon//137/2"},
{LARGE_ICON, "chrome-search://large-icon/96"},
{LARGE_ICON, "chrome-search://large-icon/-1/137/2"},
{LARGE_ICON, "chrome-search://large-icon/blah/137/2"},
{FALLBACK_ICON, "chrome-search://fallback-icon/137/3"},
{FALLBACK_ICON, "chrome-search://fallback-icon//137/3"},
{FALLBACK_ICON, "chrome-search://fallback-icon/-64,fff,,,1/137/3"},
{FALLBACK_ICON, "chrome-search://fallback-icon/springfront/137/3"},
// Use Page URL.
{LARGE_ICON, "chrome-search://large-icon/96/http://www.google.com"},
{FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/http://www.google.com"},
{THUMB, "chrome-search://thumb/http://www.google.com"},
};
std::string favicon_params = "";
InstantRestrictedID rid = 0;
MockIconURLHelper helper;
for (size_t i = 0; i < arraysize(test_cases); ++i) {
bool return_val = GetRestrictedIDFromFaviconUrl(
test_cases[i].render_view_id,
test_cases[i].transient_url,
&favicon_params,
&rid);
EXPECT_EQ(test_cases[i].expected_return_val, return_val);
EXPECT_EQ(test_cases[i].expected_favicon_params, favicon_params);
EXPECT_EQ(test_cases[i].expected_rid, rid);
favicon_params = "";
rid = 0;
GURL url;
GURL transient_url(test_cases[i].transient_url_str);
EXPECT_FALSE(TranslateIconRestrictedUrl(transient_url, test_cases[i].type,
helper, &url))
<< " for test_cases[" << i << "]";
EXPECT_TRUE(url.is_empty()) << " for test_cases[" << i << "]";
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment