Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Unified Diff: chrome/browser/history/top_sites_database.cc

Issue 560543002: [Top Sites] Encoding redirects field in TopSitesDatabase, and adding validations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/history/top_sites_database.cc
diff --git a/chrome/browser/history/top_sites_database.cc b/chrome/browser/history/top_sites_database.cc
index ff20d4db8e3756beaeec1e264ac13030bced5bce..386875f8baf8049b395b6ac9694559823364bcf1 100644
--- a/chrome/browser/history/top_sites_database.cc
+++ b/chrome/browser/history/top_sites_database.cc
@@ -78,22 +78,6 @@ bool InitTables(sql::Connection* db) {
return db->Execute(kThumbnailsSql);
}
-// Encodes redirects into a string.
-std::string GetRedirects(const history::MostVisitedURL& url) {
- std::vector<std::string> redirects;
- for (size_t i = 0; i < url.redirects.size(); i++)
- redirects.push_back(url.redirects[i].spec());
- return JoinString(redirects, ' ');
-}
-
-// Decodes redirects from a string and sets them for the url.
-void SetRedirects(const std::string& redirects, history::MostVisitedURL* url) {
- std::vector<std::string> redirects_vector;
- base::SplitStringAlongWhitespace(redirects, &redirects_vector);
- for (size_t i = 0; i < redirects_vector.size(); ++i)
- url->redirects.push_back(GURL(redirects_vector[i]));
-}
-
// Track various failure (and success) cases in recovery code.
//
// TODO(shess): The recovery code is complete, but by nature runs in challenging
@@ -132,6 +116,8 @@ enum RecoveryEventType {
RECOVERY_EVENT_MAX,
};
+const char kDataUrlPrefix[] = "data:";
+
void RecordRecoveryEvent(RecoveryEventType recovery_event) {
UMA_HISTOGRAM_ENUMERATION("History.TopSitesRecovery",
recovery_event, RECOVERY_EVENT_MAX);
@@ -460,8 +446,8 @@ void TopSitesDatabase::GetPageThumbnails(MostVisitedURLList* urls,
url.title = statement.ColumnString16(2);
url.last_forced_time =
base::Time::FromInternalValue(statement.ColumnInt64(10));
- std::string redirects = statement.ColumnString(4);
- SetRedirects(redirects, &url);
+ std::string encoded_redirects = statement.ColumnString(4);
+ DecodeRedirects(encoded_redirects, &url.redirects);
urls->push_back(url);
std::vector<unsigned char> data;
@@ -510,7 +496,7 @@ bool TopSitesDatabase::UpdatePageThumbnail(
statement.BindBlob(1, thumbnail.thumbnail->front(),
static_cast<int>(thumbnail.thumbnail->size()));
}
- statement.BindString(2, GetRedirects(url));
+ statement.BindString(2, EncodeRedirects(url.redirects));
const ThumbnailScore& score = thumbnail.thumbnail_score;
statement.BindDouble(3, score.boring_score);
statement.BindBool(4, score.good_clipping);
@@ -539,7 +525,7 @@ void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url,
statement.BindBlob(3, thumbnail.thumbnail->front(),
static_cast<int>(thumbnail.thumbnail->size()));
}
- statement.BindString(4, GetRedirects(url));
+ statement.BindString(4, EncodeRedirects(url.redirects));
const ThumbnailScore& score = thumbnail.thumbnail_score;
statement.BindDouble(5, score.boring_score);
statement.BindBool(6, score.good_clipping);
@@ -559,6 +545,102 @@ void TopSitesDatabase::AddPageThumbnail(const MostVisitedURL& url,
UpdatePageRankNoTransaction(url, new_rank);
}
+// static
+std::string TopSitesDatabase::EncodeCSVString(
+ const std::vector<std::string> str_list) {
+ std::string csv;
+ for (std::vector<std::string>::const_iterator it = str_list.begin();
+ it != str_list.end(); ++it) {
+ const std::string& str = *it;
+ if (it != str_list.begin())
+ csv += ',';
+ csv += '"';
+ for (std::string::const_iterator jt = str.begin(); jt != str.end(); ++jt) {
+ if (*jt == '"')
+ csv += '"';
beaudoin 2014/09/09 21:32:27 Looks like you escape quotes as two quotes. Your c
huangs 2014/09/11 01:58:13 Comment in .h file updated.
+ csv += *jt;
+ }
+ csv += '"';
+ }
+ return csv;
+}
+
+// static
+bool TopSitesDatabase::DecodeCSVString(const std::string csv,
+ std::vector<std::string>* str_list) {
+ if (csv.empty()) {
+ str_list->clear();
+ return true;
+ }
+
+ enum {
+ SEEK_QUOTE,
+ READ_STRING,
+ SAW_ONE_QUOTE
+ } state = SEEK_QUOTE;
+ std::vector<std::string> out_list;
+ std::string str;
+ for (std::string::const_iterator it = csv.begin(); it != csv.end(); ++it) {
+ const char ch = *it;
+ if (state == SEEK_QUOTE) {
+ if (ch != '"')
+ return false;
+ state = READ_STRING;
+ } else if (state == READ_STRING) {
+ if (ch == '"')
+ state = SAW_ONE_QUOTE;
+ else
+ str += ch;
+ } else if (state == SAW_ONE_QUOTE) {
+ if (ch == '"') {
+ str += ch;
+ state = READ_STRING;
+ } else if (ch == ',') {
+ out_list.push_back(str);
+ str.clear();
+ state = SEEK_QUOTE;
+ } else {
+ return false;
beaudoin 2014/09/09 21:32:27 You're strict about the fact that the comma must i
huangs 2014/09/11 01:58:13 Done.
+ }
+ } else {
+ NOTREACHED();
+ return false;
+ }
+ }
+ if (state != SAW_ONE_QUOTE)
+ return false;
+ out_list.push_back(str);
+ str_list->swap(out_list);
+ return true;
+}
+
+// static
+std::string TopSitesDatabase::EncodeRedirects(const RedirectList& redirects) {
+ std::vector<std::string> valid_urls;
+ for (size_t i = 0; i < redirects.size(); i++) {
+ // Example of invalid URL that may end up here:
+ // "data:text/plain,this string contains space".
+ if (redirects[i].is_valid())
+ valid_urls.push_back(redirects[i].spec());
+ }
+ return EncodeCSVString(valid_urls);
+}
+
+// static
+void TopSitesDatabase::DecodeRedirects(const std::string& encoded_redirects,
+ RedirectList* redirects) {
+ std::vector<std::string> redirects_vector;
+ if (!DecodeCSVString(encoded_redirects, &redirects_vector)) {
+ // Fall back to space-delimited list for backward compatibility.
+ base::SplitStringAlongWhitespace(encoded_redirects, &redirects_vector);
beaudoin 2014/09/09 21:32:27 I see, so you support DB in the old format too. It
huangs 2014/09/11 01:58:13 Changing version, but have to maintain backward co
+ }
+ for (size_t i = 0; i < redirects_vector.size(); ++i) {
+ GURL redirect_url(redirects_vector[i]);
+ if (redirect_url.is_valid())
+ redirects->push_back(redirect_url);
+ }
+}
+
void TopSitesDatabase::UpdatePageRank(const MostVisitedURL& url,
int new_rank) {
DCHECK((url.last_forced_time.ToInternalValue() == 0) ==

Powered by Google App Engine
This is Rietveld 408576698