summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/search_engines/template_url.cc29
-rw-r--r--chrome/browser/search_engines/template_url.h19
-rw-r--r--chrome/browser/search_engines/template_url_unittest.cc71
3 files changed, 104 insertions, 15 deletions
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc
index 26da6fa..9ff827c 100644
--- a/chrome/browser/search_engines/template_url.cc
+++ b/chrome/browser/search_engines/template_url.cc
@@ -97,6 +97,7 @@ bool TemplateURLRef::ParseParameter(size_t start,
length--;
}
std::wstring parameter(url->substr(start + 1, length));
+ std::wstring full_parameter(url->substr(start, end - start + 1));
// Remove the parameter from the string.
url->erase(start, end - start + 1);
if (parameter == kSearchTermsParameter) {
@@ -137,9 +138,9 @@ bool TemplateURLRef::ParseParameter(size_t start,
} else if (parameter == kGoogleUnescapedSearchTermsParameter) {
replacements->push_back(Replacement(GOOGLE_UNESCAPED_SEARCH_TERMS,
static_cast<int>(start)));
- } else if (!optional) {
- // Unknown required parameter. No idea what to replace this with,
- // so fail.
+ } else {
+ // It can be some garbage but can also be a javascript block. Put it back.
+ url->insert(start, full_parameter);
return false;
}
return true;
@@ -153,14 +154,22 @@ std::wstring TemplateURLRef::ParseURL(const std::wstring& url,
for (size_t last = 0; last != std::string::npos; ) {
last = parsed_url.find(kStartParameter, last);
if (last != std::string::npos) {
- size_t endTemplate = parsed_url.find(kEndParameter, last);
- if (endTemplate != std::string::npos) {
- if (!ParseParameter(last, endTemplate, &parsed_url, replacements)) {
- // Not a valid parameter, return.
- return std::wstring();
+ size_t template_end = parsed_url.find(kEndParameter, last);
+ if (template_end != std::string::npos) {
+ // Since we allow Javascript in the URL, {} pairs could be nested. Match
+ // only leaf pairs with supported parameters.
+ size_t next_template_start = parsed_url.find(kStartParameter, last + 1);
+ if (next_template_start == std::string::npos ||
+ next_template_start > template_end) {
+ // If successful, ParseParameter erases from the string as such no
+ // need to update |last|. If failed, move |last| to the end of pair.
+ if (!ParseParameter(last, template_end, &parsed_url, replacements)) {
+ // |template_end| + 1 may be beyond the end of the string.
+ last = template_end;
+ }
+ } else {
+ last = next_template_start;
}
- // ParseParamter erases from the string, as such we don't need
- // to update last.
} else {
// Open brace without a closing brace, return.
return std::wstring();
diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h
index 9462363..90cd734 100644
--- a/chrome/browser/search_engines/template_url.h
+++ b/chrome/browser/search_engines/template_url.h
@@ -5,10 +5,12 @@
#ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
#define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
+#include <string>
#include <vector>
#include "base/time.h"
#include "googleurl/src/gurl.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
class TemplateURL;
@@ -111,6 +113,13 @@ class TemplateURLRef {
friend class TemplateURL;
friend class TemplateURLModelTest;
friend class TemplateURLTest;
+ FRIEND_TEST(TemplateURLTest, ParseParameterKnown);
+ FRIEND_TEST(TemplateURLTest, ParseParameterUnknown);
+ FRIEND_TEST(TemplateURLTest, ParseURLEmpty);
+ FRIEND_TEST(TemplateURLTest, ParseURLNoTemplateEnd);
+ FRIEND_TEST(TemplateURLTest, ParseURLNoKnownParameters);
+ FRIEND_TEST(TemplateURLTest, ParseURLTwoParameters);
+ FRIEND_TEST(TemplateURLTest, ParseURLNestedParameter);
// Enumeration of the known types.
enum ReplacementType {
@@ -146,9 +155,11 @@ class TemplateURLRef {
// range of the parameter in the url, including the braces. If the parameter
// is valid, url is updated to reflect the appropriate parameter. If
// the parameter is one of the known parameters an element is added to
- // replacements indicating the type and range of the element.
+ // replacements indicating the type and range of the element. The original
+ // parameter is erased from the url.
//
- // If the parameter is not a known parameter, false is returned.
+ // If the parameter is not a known parameter, it's not erased and false is
+ // returned.
bool ParseParameter(size_t start,
size_t end,
std::wstring* url,
@@ -157,8 +168,8 @@ class TemplateURLRef {
// Parses the specified url, replacing parameters as necessary. If
// successful, valid is set to true, and the parsed url is returned. For all
// known parameters that are encountered an entry is added to replacements.
- // If there is an error parsing (unknown parameter, or bogus url), valid is
- // set to false, and an empty string is returned.
+ // If there is an error parsing the url, valid is set to false, and an empty
+ // string is returned.
std::wstring ParseURL(const std::wstring& url,
Replacements* replacements,
bool* valid) const;
diff --git a/chrome/browser/search_engines/template_url_unittest.cc b/chrome/browser/search_engines/template_url_unittest.cc
index 261adf0..fd468cb 100644
--- a/chrome/browser/search_engines/template_url_unittest.cc
+++ b/chrome/browser/search_engines/template_url_unittest.cc
@@ -369,7 +369,6 @@ TEST_F(TemplateURLTest, HostAndSearchTermKey) {
// Single term with extra chars in value should match.
{ L"http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
-
};
TemplateURL t_url;
@@ -411,3 +410,73 @@ TEST_F(TemplateURLTest, Keyword) {
EXPECT_FALSE(t_url.autogenerate_keyword());
EXPECT_EQ(L"foo", t_url.keyword());
}
+
+TEST_F(TemplateURLTest, ParseParameterKnown) {
+ std::wstring parsed_url(L"{searchTerms}");
+ TemplateURLRef url_ref(parsed_url, 0, 0);
+ TemplateURLRef::Replacements replacements;
+ EXPECT_TRUE(url_ref.ParseParameter(0, 12, &parsed_url, &replacements));
+ EXPECT_EQ(std::wstring(), parsed_url);
+ ASSERT_EQ(1U, replacements.size());
+ EXPECT_EQ(0, replacements[0].index);
+ EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
+}
+
+TEST_F(TemplateURLTest, ParseParameterUnknown) {
+ std::wstring parsed_url(L"{}");
+ TemplateURLRef url_ref(parsed_url, 0, 0);
+ TemplateURLRef::Replacements replacements;
+ EXPECT_FALSE(url_ref.ParseParameter(0, 1, &parsed_url, &replacements));
+ EXPECT_EQ(L"{}", parsed_url);
+ EXPECT_TRUE(replacements.empty());
+}
+
+TEST_F(TemplateURLTest, ParseURLEmpty) {
+ TemplateURLRef url_ref(L"", 0, 0);
+ TemplateURLRef::Replacements replacements;
+ bool valid = false;
+ EXPECT_EQ(std::wstring(), url_ref.ParseURL(L"", &replacements, &valid));
+ EXPECT_TRUE(replacements.empty());
+ EXPECT_TRUE(valid);
+}
+
+TEST_F(TemplateURLTest, ParseURLNoTemplateEnd) {
+ TemplateURLRef url_ref(L"{", 0, 0);
+ TemplateURLRef::Replacements replacements;
+ bool valid = false;
+ EXPECT_EQ(std::wstring(), url_ref.ParseURL(L"{", &replacements, &valid));
+ EXPECT_TRUE(replacements.empty());
+ EXPECT_FALSE(valid);
+}
+
+TEST_F(TemplateURLTest, ParseURLNoKnownParameters) {
+ TemplateURLRef url_ref(L"{}", 0, 0);
+ TemplateURLRef::Replacements replacements;
+ bool valid = false;
+ EXPECT_EQ(L"{}", url_ref.ParseURL(L"{}", &replacements, &valid));
+ EXPECT_TRUE(replacements.empty());
+ EXPECT_TRUE(valid);
+}
+
+TEST_F(TemplateURLTest, ParseURLTwoParameters) {
+ TemplateURLRef url_ref(L"{}{{%s}}", 0, 0);
+ TemplateURLRef::Replacements replacements;
+ bool valid = false;
+ EXPECT_EQ(L"{}{}",
+ url_ref.ParseURL(L"{}{{searchTerms}}", &replacements, &valid));
+ ASSERT_EQ(1U, replacements.size());
+ EXPECT_EQ(3, replacements[0].index);
+ EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
+ EXPECT_TRUE(valid);
+}
+
+TEST_F(TemplateURLTest, ParseURLNestedParameter) {
+ TemplateURLRef url_ref(L"{%s", 0, 0);
+ TemplateURLRef::Replacements replacements;
+ bool valid = false;
+ EXPECT_EQ(L"{", url_ref.ParseURL(L"{{searchTerms}", &replacements, &valid));
+ ASSERT_EQ(1U, replacements.size());
+ EXPECT_EQ(1, replacements[0].index);
+ EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
+ EXPECT_TRUE(valid);
+}