| Index: chrome/browser/privacy_blacklist/blacklist.cc
|
| ===================================================================
|
| --- chrome/browser/privacy_blacklist/blacklist.cc (revision 20880)
|
| +++ chrome/browser/privacy_blacklist/blacklist.cc (working copy)
|
| @@ -9,17 +9,15 @@
|
|
|
| #include "base/file_path.h"
|
| #include "base/file_util.h"
|
| +#include "base/string_util.h"
|
| #include "chrome/browser/privacy_blacklist/blacklist_store.h"
|
| +#include "chrome/common/url_constants.h"
|
| #include "net/http/http_util.h"
|
|
|
| #define STRINGIZE(s) #s
|
|
|
| namespace {
|
|
|
| -bool matches(const std::string& pattern, const std::string& url) {
|
| - return url.find(pattern) != std::string::npos;
|
| -}
|
| -
|
| const char* const cookie_headers[2] = { "cookie", "set-cookie" };
|
|
|
| } // namespace
|
| @@ -47,6 +45,49 @@
|
| return 0;
|
| }
|
|
|
| +bool Blacklist::Matches(const std::string& pattern, const std::string& url) {
|
| + if (pattern.size() > url.size())
|
| + return false;
|
| +
|
| + std::string::size_type p = 0;
|
| + std::string::size_type u = 0;
|
| +
|
| + while (pattern[p] != '\0' && url[u] != '\0') {
|
| + if (pattern[p] == '@') {
|
| + while (pattern[++p] == '@'); // Consecutive @ are redundant.
|
| +
|
| + if (pattern[p] == '\0')
|
| + return true; // Nothing to match after the @.
|
| +
|
| + // Look for another wildcard to determine pattern-chunk.
|
| + std::string::size_type tp = pattern.find_first_of("@", p);
|
| +
|
| + // If it must match until the end, compare the last characters.
|
| + if (tp == std::string::npos) {
|
| + std::string::size_type ur = url.size() - u;
|
| + std::string::size_type pr = pattern.size() - p;
|
| + return (pr <= ur) &&
|
| + (url.compare(url.size() - pr, pr, pattern.c_str() + p) == 0);
|
| + }
|
| +
|
| + // Else find the pattern chunk which is pattern[p:tp]
|
| + std::string::size_type tu = url.find(pattern.c_str() + p, u, tp - p);
|
| + if (tu == std::string::npos)
|
| + return false; // Pattern chunk not found.
|
| +
|
| + // Since tp is strictly greater than p, both u and p always increase.
|
| + u = tu + tp - p;
|
| + p = tp;
|
| + continue;
|
| + }
|
| +
|
| + // Match non-wildcard character.
|
| + if (pattern[p++] != url[u++])
|
| + return false;
|
| + }
|
| + return pattern[p] == '\0';
|
| +}
|
| +
|
| bool Blacklist::Entry::MatchType(const std::string& type) const {
|
| return std::find(types_.begin(), types_.end(), type) != types_.end();
|
| }
|
| @@ -80,6 +121,27 @@
|
| }
|
| }
|
|
|
| +bool Blacklist::Match::MatchType(const std::string& type) const {
|
| + for (std::vector<const Entry*>::const_iterator i = entries_.begin();
|
| + i != entries_.end(); ++i) {
|
| + if ((*i)->MatchType(type))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool Blacklist::Match::IsBlocked(const GURL& url) const {
|
| + return (attributes_ & kBlockAll) ||
|
| + ((attributes_ & kBlockUnsecure) && !url.SchemeIsSecure());
|
| +}
|
| +
|
| +Blacklist::Match::Match() : attributes_(0) {}
|
| +
|
| +void Blacklist::Match::AddEntry(const Entry* entry) {
|
| + attributes_ |= entry->attributes();
|
| + entries_.push_back(entry);
|
| +}
|
| +
|
| Blacklist::Blacklist(const FilePath& file) {
|
| // No blacklist, nothing to load.
|
| if (file.value().empty())
|
| @@ -122,12 +184,24 @@
|
|
|
| // Returns a pointer to the Blacklist-owned entry which matches the given
|
| // URL. If no matching Entry is found, returns null.
|
| -const Blacklist::Entry* Blacklist::findMatch(const GURL& url) const {
|
| +Blacklist::Match* Blacklist::findMatch(const GURL& url) const {
|
| + // Never match something which is not http, https or ftp.
|
| + // TODO(idanan): Investigate if this would be an inclusion test instead of an
|
| + // exclusion test and if there are other schemes to test for.
|
| + if (!url.SchemeIs(chrome::kHttpScheme) &&
|
| + !url.SchemeIs(chrome::kHttpsScheme) &&
|
| + !url.SchemeIs(chrome::kFtpScheme))
|
| + return 0;
|
| + Match* match = NULL;
|
| for (std::vector<Entry*>::const_iterator i = blacklist_.begin();
|
| - i != blacklist_.end(); ++i)
|
| - if (matches((*i)->pattern(), url.spec()))
|
| - return *i;
|
| - return 0;
|
| + i != blacklist_.end(); ++i) {
|
| + if (Matches((*i)->pattern(), url.host()+url.path())) {
|
| + if (!match)
|
| + match = new Match;
|
| + match->AddEntry(*i);
|
| + }
|
| + }
|
| + return match;
|
| }
|
|
|
| std::string Blacklist::StripCookies(const std::string& header) {
|
| @@ -135,12 +209,19 @@
|
| }
|
|
|
| std::string Blacklist::StripCookieExpiry(const std::string& cookie) {
|
| - std::string::size_type start = cookie.find("; expires=");
|
| + std::string::size_type delim = cookie.find(';');
|
| + std::string::size_type start = cookie.find("expires=", delim + 1);
|
| if (start != std::string::npos) {
|
| - std::string::size_type finish = cookie.find(";", start+1);
|
| - std::string session_cookie(cookie, 0, start);
|
| - if (finish != std::string::npos)
|
| - session_cookie.append(cookie.substr(finish));
|
| + std::string::size_type i = start;
|
| + // Make sure only whitespace precedes the expiry until a delimiter.
|
| + while (cookie[--i] != ';')
|
| + if (!IsAsciiWhitespace(cookie[i]))
|
| + return cookie;
|
| +
|
| + std::string session_cookie(cookie, 0, i);
|
| + std::string::size_type end = cookie.find(';', start + 1);
|
| + if (end != std::string::npos)
|
| + session_cookie.append(cookie.substr(end));
|
| return session_cookie;
|
| }
|
| return cookie;
|
|
|