Chromium Code Reviews| Index: components/search_engines/template_url.cc |
| diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc |
| index b4fb151639c6799de44dc0008764ebc6a051e3c2..5ef7069d4dc385cebceef452f5275b8123359ea2 100644 |
| --- a/components/search_engines/template_url.cc |
| +++ b/components/search_engines/template_url.cc |
| @@ -98,63 +98,61 @@ bool TryEncoding(const base::string16& terms, |
| return true; |
| } |
| -// Returns true if the search term placeholder is present, and also produces |
| -// the constant prefix/suffix found. |
| -bool TryMatchSearchParam(base::StringPiece text, |
| - base::StringPiece pattern, |
| - std::string* prefix, |
| - std::string* suffix) { |
| - auto pos = text.find(pattern); |
| - if (pos == base::StringPiece::npos) |
| - return false; |
| - text.substr(0, pos).CopyToString(prefix); |
| - text.substr(pos + pattern.length()).CopyToString(suffix); |
| - return true; |
| -} |
| - |
| -// Extract query key and host given a list of parameters coming from the URL |
| -// query or ref. |
| -struct SearchTermsKeyResult { |
| - std::string key; |
| - std::string value_prefix; |
| - std::string value_suffix; |
| - bool found() const { return !key.empty(); } |
| -}; |
| -SearchTermsKeyResult FindSearchTermsKey(const std::string& params) { |
| - SearchTermsKeyResult result; |
| - if (params.empty()) |
| - return result; |
| - url::Component query, key, value; |
| - query.len = static_cast<int>(params.size()); |
| - while (url::ExtractQueryKeyValue(params.c_str(), &query, &key, &value)) { |
| - if (key.is_nonempty() && value.is_nonempty()) { |
| - const base::StringPiece value_string(params.c_str() + value.begin, |
| - value.len); |
| - if (TryMatchSearchParam(value_string, kSearchTermsParameterFull, |
| - &result.value_prefix, &result.value_suffix) || |
| - TryMatchSearchParam(value_string, |
| - kGoogleUnescapedSearchTermsParameterFull, |
| - &result.value_prefix, &result.value_suffix)) { |
| - result.key = params.substr(key.begin, key.len); |
| - break; |
| +// Finds the position of the search terms' parameter in the URL component. |
| +class SearchTermLocation { |
| + public: |
| + SearchTermLocation(const base::StringPiece& url_component, |
| + url::Parsed::ComponentType url_component_type) |
| + : found_(false) { |
| + if (url_component_type == url::Parsed::PATH) { |
| + // GURL's constructor escapes "{" and "}" in the path of a passed string. |
| + found_ = |
| + TryMatchSearchParam(url_component, kSearchTermsParameterFullEscaped); |
| + } else { |
| + DCHECK((url_component_type == url::Parsed::QUERY) || |
| + (url_component_type == url::Parsed::REF)); |
| + url::Component query, key, value; |
| + query.len = static_cast<int>(url_component.size()); |
| + while (url::ExtractQueryKeyValue(url_component.data(), &query, &key, |
| + &value)) { |
| + if (key.is_nonempty() && value.is_nonempty()) { |
| + const base::StringPiece value_string = |
| + url_component.substr(value.begin, value.len); |
| + if (TryMatchSearchParam(value_string, kSearchTermsParameterFull) || |
| + TryMatchSearchParam(value_string, |
| + kGoogleUnescapedSearchTermsParameterFull)) { |
| + found_ = true; |
| + url_component.substr(key.begin, key.len).CopyToString(&key_); |
| + break; |
| + } |
| + } |
| } |
| } |
| } |
| - return result; |
| -} |
| -// Extract the position of the search terms' parameter in the URL path. |
| -bool FindSearchTermsInPath(const std::string& path, |
| - url::Component* parameter_position) { |
| - DCHECK(parameter_position); |
| - parameter_position->reset(); |
| - const size_t begin = path.find(kSearchTermsParameterFullEscaped); |
| - if (begin == std::string::npos) |
| - return false; |
| - parameter_position->begin = begin; |
| - parameter_position->len = arraysize(kSearchTermsParameterFullEscaped) - 1; |
| - return true; |
| -} |
| + bool found() const { return found_; } |
| + const std::string& key() const { return key_; } |
| + const std::string& value_prefix() const { return value_prefix_; } |
| + const std::string& value_suffix() const { return value_suffix_; } |
| + |
| + private: |
| + // Returns true if the search term placeholder is present, and also assigns |
| + // the constant prefix/suffix found. |
| + bool TryMatchSearchParam(const base::StringPiece& value, |
| + const base::StringPiece& pattern) { |
| + size_t pos = value.find(pattern); |
| + if (pos == base::StringPiece::npos) |
| + return false; |
| + value.substr(0, pos).CopyToString(&value_prefix_); |
| + value.substr(pos + pattern.length()).CopyToString(&value_suffix_); |
| + return true; |
| + } |
| + |
| + bool found_; |
| + std::string key_; |
| + std::string value_prefix_; |
| + std::string value_suffix_; |
| +}; |
|
Peter Kasting
2017/05/12 21:17:46
Nit: DISALLOW_COPY_AND_ASSIGN
Vitaly Baranov
2017/05/15 07:55:34
Done.
|
| bool IsTemplateParameterString(const std::string& param) { |
| return (param.length() > 2) && (*(param.begin()) == kStartParameter) && |
| @@ -212,7 +210,6 @@ TemplateURLRef::TemplateURLRef(const TemplateURL* owner, Type type) |
| parsed_(false), |
| valid_(false), |
| supports_replacements_(false), |
| - search_term_position_in_path_(std::string::npos), |
| search_term_key_location_(url::Parsed::QUERY), |
| prepopulated_(false) { |
| DCHECK(owner_); |
| @@ -226,7 +223,6 @@ TemplateURLRef::TemplateURLRef(const TemplateURL* owner, size_t index_in_owner) |
| parsed_(false), |
| valid_(false), |
| supports_replacements_(false), |
| - search_term_position_in_path_(std::string::npos), |
| search_term_key_location_(url::Parsed::QUERY), |
| prepopulated_(false) { |
| DCHECK(owner_); |
| @@ -393,20 +389,26 @@ const std::string& TemplateURLRef::GetSearchTermKey( |
| return search_term_key_; |
| } |
| -size_t TemplateURLRef::GetSearchTermPositionInPath( |
| +url::Parsed::ComponentType TemplateURLRef::GetSearchTermKeyLocation( |
| const SearchTermsData& search_terms_data) const { |
| ParseIfNecessary(search_terms_data); |
| - return search_term_position_in_path_; |
| + return search_term_key_location_; |
| } |
| -url::Parsed::ComponentType TemplateURLRef::GetSearchTermKeyLocation( |
| +const std::string& TemplateURLRef::GetSearchTermValuePrefix( |
| const SearchTermsData& search_terms_data) const { |
| ParseIfNecessary(search_terms_data); |
| - return search_term_key_location_; |
| + return search_term_value_prefix_; |
| +} |
| + |
| +const std::string& TemplateURLRef::GetSearchTermValueSuffix( |
| + const SearchTermsData& search_terms_data) const { |
| + ParseIfNecessary(search_terms_data); |
| + return search_term_value_suffix_; |
| } |
| base::string16 TemplateURLRef::SearchTermToString16( |
| - const std::string& term) const { |
| + const base::StringPiece& term) const { |
| const std::vector<std::string>& encodings = owner_->input_encodings(); |
| base::string16 result; |
| @@ -472,30 +474,33 @@ bool TemplateURLRef::ExtractSearchTermsFromURL( |
| return false; |
| } |
| - std::string source; |
| + base::StringPiece source; |
| url::Component position; |
| if (search_term_key_location_ == url::Parsed::PATH) { |
| - source = url.path(); |
| - |
| - // Characters in the path before and after search terms must match. |
| - if (source.length() < path_.length()) |
| - return false; |
| - position.begin = search_term_position_in_path_; |
| - position.len = source.length() - path_.length(); |
| - if (source.substr(0, position.begin) + source.substr(position.end()) != |
| - path_) |
| + source = url.path_piece(); |
| + |
| + // If the path does not contain the expected prefix and suffix, then this is |
| + // not a match. |
| + if (source.size() < (search_term_value_prefix_.size() + |
| + search_term_value_suffix_.size()) || |
| + !source.starts_with(search_term_value_prefix_) || |
| + !source.ends_with(search_term_value_suffix_)) |
| return false; |
| + position = |
| + url::MakeRange(search_term_value_prefix_.size(), |
| + source.length() - search_term_value_suffix_.size()); |
| } else { |
| DCHECK(search_term_key_location_ == url::Parsed::QUERY || |
| search_term_key_location_ == url::Parsed::REF); |
| - source = (search_term_key_location_ == url::Parsed::QUERY) ? |
| - url.query() : url.ref(); |
| + source = (search_term_key_location_ == url::Parsed::QUERY) |
| + ? url.query_piece() |
| + : url.ref_piece(); |
| url::Component query, key, value; |
| query.len = static_cast<int>(source.size()); |
| bool key_found = false; |
| - while (url::ExtractQueryKeyValue(source.c_str(), &query, &key, &value)) { |
| + while (url::ExtractQueryKeyValue(source.data(), &query, &key, &value)) { |
| if (key.is_nonempty()) { |
| if (source.substr(key.begin, key.len) == search_term_key_) { |
| // Fail if search term key is found twice. |
| @@ -539,8 +544,9 @@ void TemplateURLRef::InvalidateCachedValues() const { |
| port_.clear(); |
| path_.clear(); |
| search_term_key_.clear(); |
| - search_term_position_in_path_ = std::string::npos; |
| search_term_key_location_ = url::Parsed::QUERY; |
| + search_term_value_prefix_.clear(); |
| + search_term_value_suffix_.clear(); |
| replacements_.clear(); |
| post_params_.clear(); |
| } |
| @@ -791,35 +797,34 @@ void TemplateURLRef::ParseHostAndSearchTermKey( |
| if (!url.is_valid()) |
| return; |
| - auto query_result = FindSearchTermsKey(url.query()); |
| - auto ref_result = FindSearchTermsKey(url.ref()); |
| - url::Component parameter_position; |
| + SearchTermLocation query_result(url.query_piece(), url::Parsed::QUERY); |
| + SearchTermLocation ref_result(url.ref_piece(), url::Parsed::REF); |
| + SearchTermLocation path_result(url.path_piece(), url::Parsed::PATH); |
| const bool in_query = query_result.found(); |
| const bool in_ref = ref_result.found(); |
| - const bool in_path = FindSearchTermsInPath(url.path(), ¶meter_position); |
| + const bool in_path = path_result.found(); |
| if (in_query ? (in_ref || in_path) : (in_ref == in_path)) |
| return; // No key or multiple keys found. We only handle having one key. |
| host_ = url.host(); |
| port_ = url.port(); |
| - path_ = url.path(); |
| if (in_query) { |
| - search_term_key_ = query_result.key; |
| search_term_key_location_ = url::Parsed::QUERY; |
| - search_term_value_prefix_ = query_result.value_prefix; |
| - search_term_value_suffix_ = query_result.value_suffix; |
| + search_term_key_ = query_result.key(); |
| + search_term_value_prefix_ = query_result.value_prefix(); |
| + search_term_value_suffix_ = query_result.value_suffix(); |
| + path_ = url.path(); |
| } else if (in_ref) { |
| - search_term_key_ = ref_result.key; |
| search_term_key_location_ = url::Parsed::REF; |
| - search_term_value_prefix_ = ref_result.value_prefix; |
| - search_term_value_suffix_ = ref_result.value_suffix; |
| + search_term_key_ = ref_result.key(); |
| + search_term_value_prefix_ = ref_result.value_prefix(); |
| + search_term_value_suffix_ = ref_result.value_suffix(); |
| + path_ = url.path(); |
| } else { |
| DCHECK(in_path); |
| - DCHECK_GE(parameter_position.begin, 1); // Path must start with '/'. |
| search_term_key_location_ = url::Parsed::PATH; |
| - search_term_position_in_path_ = parameter_position.begin; |
| - // Remove the "{searchTerms}" itself from |path_|. |
| - path_.erase(parameter_position.begin, parameter_position.len); |
| + search_term_value_prefix_ = path_result.value_prefix(); |
| + search_term_value_suffix_ = path_result.value_suffix(); |
| } |
| } |