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( ...@@ -1366,10 +1366,17 @@ bool ChromeContentRendererClient::WillSendRequest(
content::RenderView::FromWebView(frame->view()); content::RenderView::FromWebView(frame->view());
SearchBox* search_box = SearchBox::Get(render_view); SearchBox* search_box = SearchBox::Get(render_view);
if (search_box && url.SchemeIs(chrome::kChromeSearchScheme)) { if (search_box && url.SchemeIs(chrome::kChromeSearchScheme)) {
if (url.host() == chrome::kChromeUIThumbnailHost) SearchBox::ImageSourceType type = SearchBox::NONE;
return search_box->GenerateThumbnailURLFromTransientURL(url, new_url); if (url.host() == chrome::kChromeUIFaviconHost)
else if (url.host() == chrome::kChromeUIFaviconHost) type = SearchBox::FAVICON;
return search_box->GenerateFaviconURLFromTransientURL(url, new_url); 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; return false;
......
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
#include <string> #include <string>
#include "base/logging.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/common/chrome_switches.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/favicon_url_parser.h"
#include "chrome/common/favicon/large_icon_url_parser.h"
#include "chrome/common/omnibox_focus_state.h" #include "chrome/common/omnibox_focus_state.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
...@@ -49,99 +52,180 @@ bool AreMostVisitedItemsEqual( ...@@ -49,99 +52,180 @@ bool AreMostVisitedItemsEqual(
return true; 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
namespace internal { // for testing namespace internal { // for testing
// Parses |path| and fills in |id| with the InstantRestrictedID obtained from // Parses "<view_id>/<restricted_id>". If successful, assigns
// the |path|. |render_view_id| is the ID of the associated RenderView. // |*view_id| := "<view_id>", |*rid| := "<restricted_id>", and returns true.
// bool ParseViewIdAndRestrictedId(const std::string id_part,
// |path| is a pair of |render_view_id| and |restricted_id|, and it is int* view_id_out,
// contained in Instant Extended URLs. A valid |path| is in the form: InstantRestrictedID* rid_out) {
// <render_view_id>/<restricted_id> DCHECK(view_id_out);
// DCHECK(rid_out);
// 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) {
// Check that the path is of Most visited item ID form. // Check that the path is of Most visited item ID form.
std::vector<std::string> tokens; std::vector<std::string> tokens;
if (Tokenize(path, "/", &tokens) != 2) if (Tokenize(id_part, "/", &tokens) != 2)
return false; return false;
int view_id = 0; int view_id;
if (!base::StringToInt(tokens[0], &view_id) || view_id != render_view_id) InstantRestrictedID rid;
if (!base::StringToInt(tokens[0], &view_id) || view_id < 0 ||
!base::StringToInt(tokens[1], &rid) || rid < 0)
return false; return false;
return base::StringToInt(tokens[1], id);
*view_id_out = view_id;
*rid_out = rid;
return true;
} }
bool GetRestrictedIDFromFaviconUrl(int render_view_id, // Takes icon |url| of given |type|, e.g., FAVICON looking like
const GURL& url, //
std::string* favicon_params, // chrome-search://favicon/<view_id>/<restricted_id>
InstantRestrictedID* rid) { // 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. // Strip leading slash.
std::string raw_path = url.path(); std::string raw_path = url.path();
DCHECK_GT(raw_path.length(), (size_t) 0); DCHECK_GT(raw_path.length(), (size_t) 0);
DCHECK_EQ(raw_path[0], '/'); DCHECK_EQ(raw_path[0], '/');
raw_path = raw_path.substr(1); raw_path = raw_path.substr(1);
chrome::ParsedFaviconPath parsed; int path_index = GetImagePathStartOfPageURL(type, raw_path);
if (!chrome::ParseFaviconPath(raw_path, favicon_base::FAVICON, &parsed)) if (path_index < 0)
return false;
std::string id_part = raw_path.substr(path_index);
if (!ParseViewIdAndRestrictedId(id_part, view_id, rid))
return false; return false;
// The part of the URL which details the favicon parameters should be returned *param_part = raw_path.substr(0, path_index);
// 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;
return true; return true;
} }
// Parses a thumbnail |url| and fills in |id| with the InstantRestrictedID bool TranslateIconRestrictedUrl(const GURL& transient_url,
// obtained from the |url|. |render_view_id| is the ID of the associated SearchBox::ImageSourceType type,
// RenderView. const SearchBox::IconURLHelper& helper,
// GURL* url) {
// Valid |url| forms: std::string params;
// chrome-search://thumb/<view_id>/<restricted_id> int view_id = -1;
// InstantRestrictedID rid = -1;
// 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. if (!internal::ParseIconRestrictedUrl(
bool GetRestrictedIDFromThumbnailUrl(int render_view_id, transient_url, type, &params, &view_id, &rid) ||
const GURL& url, view_id != helper.GetViewID()) {
InstantRestrictedID* id) { if (type == SearchBox::FAVICON) {
// Strip leading slash. *url = GURL(base::StringPrintf("chrome-search://%s/",
std::string path = url.path(); GetIconTypeUrlHost(SearchBox::FAVICON)));
DCHECK_GT(path.length(), (size_t) 0); return true;
DCHECK_EQ(path[0], '/'); }
path = path.substr(1); 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 } // namespace internal
SearchBox::IconURLHelper::IconURLHelper() {
}
SearchBox::IconURLHelper::~IconURLHelper() {
}
SearchBox::SearchBox(content::RenderView* render_view) SearchBox::SearchBox(content::RenderView* render_view)
: content::RenderViewObserver(render_view), : content::RenderViewObserver(render_view),
content::RenderViewObserverTracker<SearchBox>(render_view), content::RenderViewObserverTracker<SearchBox>(render_view),
...@@ -201,40 +285,11 @@ void SearchBox::DeleteMostVisitedItem( ...@@ -201,40 +285,11 @@ void SearchBox::DeleteMostVisitedItem(
GetURLForMostVisitedItem(most_visited_item_id))); GetURLForMostVisitedItem(most_visited_item_id)));
} }
bool SearchBox::GenerateFaviconURLFromTransientURL(const GURL& transient_url, bool SearchBox::GenerateImageURLFromTransientURL(const GURL& transient_url,
GURL* url) const { ImageSourceType type,
std::string favicon_params; GURL* url) const {
InstantRestrictedID rid = -1; SearchBoxIconURLHelper helper(this);
bool success = internal::GetRestrictedIDFromFaviconUrl( return internal::TranslateIconRestrictedUrl(transient_url, type, helper, url);
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;
} }
void SearchBox::GetMostVisitedItems( void SearchBox::GetMostVisitedItems(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_ #ifndef CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_
#define CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_ #define CHROME_RENDERER_SEARCHBOX_SEARCHBOX_H_
#include <string>
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
...@@ -25,6 +26,27 @@ class RenderView; ...@@ -25,6 +26,27 @@ class RenderView;
class SearchBox : public content::RenderViewObserver, class SearchBox : public content::RenderViewObserver,
public content::RenderViewObserverTracker<SearchBox> { public content::RenderViewObserverTracker<SearchBox> {
public: 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); explicit SearchBox(content::RenderView* render_view);
~SearchBox() override; ~SearchBox() override;
...@@ -46,27 +68,35 @@ class SearchBox : public content::RenderViewObserver, ...@@ -46,27 +68,35 @@ class SearchBox : public content::RenderViewObserver,
// Sends ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem to the browser. // Sends ChromeViewHostMsg_SearchBoxDeleteMostVisitedItem to the browser.
void DeleteMostVisitedItem(InstantRestrictedID most_visited_item_id); void DeleteMostVisitedItem(InstantRestrictedID most_visited_item_id);
// Generates the favicon URL of the most visited item specified by the // Generates the image URL of |type| for the most visited item specified in
// |transient_url|. If the |transient_url| is valid, returns true and fills in // |transient_url|. If |transient_url| is valid, |url| with a translated URL
// |url|. If the |transient_url| is invalid, returns true and |url| is set to // and returns true. Otherwise it depends on |type|:
// "chrome-search://favicon/" in order to prevent the invalid URL to be // - FAVICON: Returns true and renders an URL to display the default favicon.
// requested. // - 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/<view_id>/<restricted_id>
// chrome-search://favicon/<favicon_parameters>/<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> // 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. // Returns the latest most visited items sent by the browser.
void GetMostVisitedItems( void GetMostVisitedItems(
......
...@@ -2,231 +2,323 @@ ...@@ -2,231 +2,323 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/renderer/searchbox/searchbox.h"
#include <map>
#include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "chrome/common/instant_types.h" #include "chrome/common/instant_types.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.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 { namespace internal {
// Defined in searchbox.cc // Defined in searchbox.cc
bool GetRestrictedIDFromThumbnailUrl(int render_view_id, bool ParseViewIdAndRestrictedId(const std::string id_part,
const GURL& url, int* view_id_out,
InstantRestrictedID* id); 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 // Defined in searchbox.cc
bool GetRestrictedIDFromFaviconUrl(int render_view_id, bool TranslateIconRestrictedUrl(const GURL& transient_url,
const GURL& url, SearchBox::ImageSourceType type,
std::string* favicon_params, const SearchBox::IconURLHelper& helper,
InstantRestrictedID* rid); GURL* url);
TEST(SearchBoxUtilTest, GetInstantRestrictedIDFromTransientURL) { TEST(SearchBoxUtilTest, ParseViewIdAndRestrictedIdSuccess) {
const int kInvalidRenderViewID = 920; int view_id = -1;
const int kValidRenderViewID = 1; InstantRestrictedID rid = -1;
const struct { EXPECT_TRUE(ParseViewIdAndRestrictedId("2/3", &view_id, &rid));
int render_view_id; EXPECT_EQ(2, view_id);
GURL transient_url; 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; InstantRestrictedID expected_rid;
bool expected_return_val;
} test_cases[] = { } test_cases[] = {
// RenderView ID matches the view id specified in the transient url. {FAVICON, "chrome-search://favicon/1/2", "", 1, 2},
{kValidRenderViewID, GURL("chrome-search://favicon/1/2"), 2, true}, {FAVICON, "chrome-search://favicon/size/16@2x/3/4", "size/16@2x/", 3, 4},
{kValidRenderViewID, GURL("chrome-search://thumb/1/2"), 2, true}, {FAVICON, "chrome-search://favicon/largest/5/6", "largest/", 5, 6},
{FAVICON, "chrome-search://favicon/origin/7/8", "origin/", 7, 8},
// RenderView ID does not match the view id specified in the transient url. {FAVICON, "chrome-search://favicon/iconurl/9/10", "iconurl/", 9, 10},
{kInvalidRenderViewID, GURL("chrome-search://favicon/1/2"), 0, false}, {LARGE_ICON, "chrome-search://large-icon/96/1/2", "96/", 1, 2},
{kInvalidRenderViewID, GURL("chrome-search://thumb/1/2"), 0, false}, {LARGE_ICON, "chrome-search://large-icon/1/3/4", "1/", 3, 4},
// Size restriction is *not* enforced during parsing, but later.
// Invalid transient urls. {LARGE_ICON, "chrome-search://large-icon/1000000/5/6", "1000000/", 5, 6},
{kValidRenderViewID, GURL("chrome-search://thumb"), 0, false}, {FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/1/2", ",,,,/", 1, 2},
{kValidRenderViewID, GURL("chrome-search://thumb/"), 0, false}, {FALLBACK_ICON, "chrome-search://fallback-icon/1,,,,/3/4", "1,,,,/", 3, 4},
{kValidRenderViewID, GURL("chrome-search://thumb/123"), 0, false}, {FALLBACK_ICON, "chrome-search://fallback-icon/64,fff,black,0.4,0.6/5/6",
{kValidRenderViewID, GURL("chrome-search://thumb/xyz"), 0, false}, "64,fff,black,0.4,0.6/", 5, 6},
{kValidRenderViewID, GURL("chrome-search://thumb/123/"), 0, false}, {THUMB, "chrome-search://thumb/1/2", "", 1, 2},
{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}
}; };
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) { for (size_t i = 0; i < arraysize(test_cases); ++i) {
bool return_val = GetRestrictedIDFromThumbnailUrl( std::string param_part = "(unwritten)";
test_cases[i].render_view_id, test_cases[i].transient_url, &rid); int view_id = -1;
EXPECT_EQ(test_cases[i].expected_return_val, return_val); InstantRestrictedID rid = -1;
EXPECT_EQ(test_cases[i].expected_rid, rid); EXPECT_FALSE(ParseIconRestrictedUrl(GURL(test_cases[i].transient_url_str),
rid = 0; 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) { TEST(SearchBoxUtilTest, TranslateIconRestrictedUrlSuccess) {
const int kInvalidRenderViewID = 920; struct {
const int kValidRenderViewID = 1; 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 { MockIconURLHelper helper;
int render_view_id; for (size_t i = 0; i < arraysize(test_cases); ++i) {
GURL transient_url; GURL url;
std::string expected_favicon_params; GURL transient_url(test_cases[i].transient_url_str);
InstantRestrictedID expected_rid; EXPECT_TRUE(TranslateIconRestrictedUrl(transient_url, test_cases[i].type,
bool expected_return_val; 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[] = { } test_cases[] = {
// RenderView ID matches the view id specified in the transient url. // Empty.
{ {LARGE_ICON, "chrome-search://large-icon/"},
kValidRenderViewID, {FALLBACK_ICON, "chrome-search://fallback-icon/"},
GURL("chrome-search://favicon/1/2"), {THUMB, "chrome-search://thumb/"},
"", // Bad view_id.
2, {LARGE_ICON, "chrome-search://large-icon/64/314/2"},
true {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"},
kValidRenderViewID, {THUMB, "chrome-search://thumb/314/1"},
GURL("chrome-search://favicon/size/16@2x/1/2"), // Missing rid.
"size/16@2x/", {LARGE_ICON, "chrome-search://large-icon/64/137/"},
2, {LARGE_ICON, "chrome-search://large-icon/64/137/blah"},
true {FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/137/"},
}, {THUMB, "chrome-search://thumb/314/"},
{ // Bad params.
kValidRenderViewID, {LARGE_ICON, "chrome-search://large-icon/137/2"},
GURL("chrome-search://favicon/largest/1/2"), {LARGE_ICON, "chrome-search://large-icon//137/2"},
"largest/", {LARGE_ICON, "chrome-search://large-icon/96"},
2, {LARGE_ICON, "chrome-search://large-icon/-1/137/2"},
true {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"},
kValidRenderViewID, {FALLBACK_ICON, "chrome-search://fallback-icon/-64,fff,,,1/137/3"},
GURL("chrome-search://favicon/origin/1/2"), {FALLBACK_ICON, "chrome-search://fallback-icon/springfront/137/3"},
"origin/", // Use Page URL.
2, {LARGE_ICON, "chrome-search://large-icon/96/http://www.google.com"},
true {FALLBACK_ICON, "chrome-search://fallback-icon/,,,,/http://www.google.com"},
}, {THUMB, "chrome-search://thumb/http://www.google.com"},
{
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
}
}; };
std::string favicon_params = ""; MockIconURLHelper helper;
InstantRestrictedID rid = 0;
for (size_t i = 0; i < arraysize(test_cases); ++i) { for (size_t i = 0; i < arraysize(test_cases); ++i) {
bool return_val = GetRestrictedIDFromFaviconUrl( GURL url;
test_cases[i].render_view_id, GURL transient_url(test_cases[i].transient_url_str);
test_cases[i].transient_url, EXPECT_FALSE(TranslateIconRestrictedUrl(transient_url, test_cases[i].type,
&favicon_params, helper, &url))
&rid); << " for test_cases[" << i << "]";
EXPECT_EQ(test_cases[i].expected_return_val, return_val); EXPECT_TRUE(url.is_empty()) << " for test_cases[" << i << "]";
EXPECT_EQ(test_cases[i].expected_favicon_params, favicon_params);
EXPECT_EQ(test_cases[i].expected_rid, rid);
favicon_params = "";
rid = 0;
} }
} }
......
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