summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete
diff options
context:
space:
mode:
authormariakhomenko@chromium.org <mariakhomenko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-03 12:00:01 +0000
committermariakhomenko@chromium.org <mariakhomenko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-03 12:00:01 +0000
commit2e8c601f54f7ac7ac786c99f5a3b0bb8246d16bf (patch)
tree247cac8f7ba11f69bfc5499ddf6183b3fbc355ce /chrome/browser/autocomplete
parent31d6d17ee26de3b4007689ab01d5e8842f2f2c53 (diff)
downloadchromium_src-2e8c601f54f7ac7ac786c99f5a3b0bb8246d16bf.zip
chromium_src-2e8c601f54f7ac7ac786c99f5a3b0bb8246d16bf.tar.gz
chromium_src-2e8c601f54f7ac7ac786c99f5a3b0bb8246d16bf.tar.bz2
Ensure zero suggest can handle XSSI-escaped output.
Zero suggest request re-uses the same URL as regular suggest and therefore will be requesting xssi=t by default. We should make sure the output is then correctly parsed. BUG= Review URL: https://codereview.chromium.org/96753004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238360 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
-rw-r--r--chrome/browser/autocomplete/search_provider.cc39
-rw-r--r--chrome/browser/autocomplete/search_provider.h5
-rw-r--r--chrome/browser/autocomplete/search_provider_unittest.cc28
-rw-r--r--chrome/browser/autocomplete/zero_suggest_provider.cc4
4 files changed, 54 insertions, 22 deletions
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index 8fefaf3..a606d97 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -653,24 +653,8 @@ void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) {
}
}
- // The JSON response should be an array.
- for (size_t response_start_index = json_data.find("["), i = 0;
- response_start_index != std::string::npos && i < 5;
- response_start_index = json_data.find("[", 1), i++) {
- // Remove any XSSI guards to allow for JSON parsing.
- if (response_start_index > 0)
- json_data.erase(0, response_start_index);
-
- JSONStringValueSerializer deserializer(json_data);
- deserializer.set_allow_trailing_comma(true);
- int error_code = 0;
- scoped_ptr<Value> data(deserializer.Deserialize(&error_code, NULL));
- if (error_code == 0) {
- results_updated = data.get() &&
- ParseSuggestResults(data.get(), is_keyword);
- break;
- }
- }
+ scoped_ptr<Value> data(DeserializeJsonData(json_data));
+ results_updated = data.get() && ParseSuggestResults(data.get(), is_keyword);
}
UpdateMatches();
@@ -1040,6 +1024,25 @@ net::URLFetcher* SearchProvider::CreateSuggestFetcher(
return fetcher;
}
+scoped_ptr<Value> SearchProvider::DeserializeJsonData(std::string json_data) {
+ // The JSON response should be an array.
+ for (size_t response_start_index = json_data.find("["), i = 0;
+ response_start_index != std::string::npos && i < 5;
+ response_start_index = json_data.find("[", 1), i++) {
+ // Remove any XSSI guards to allow for JSON parsing.
+ if (response_start_index > 0)
+ json_data.erase(0, response_start_index);
+
+ JSONStringValueSerializer deserializer(json_data);
+ deserializer.set_allow_trailing_comma(true);
+ int error_code = 0;
+ scoped_ptr<Value> data(deserializer.Deserialize(&error_code, NULL));
+ if (error_code == 0)
+ return data.Pass();
+ }
+ return scoped_ptr<Value>();
+}
+
bool SearchProvider::ParseSuggestResults(Value* root_val, bool is_keyword) {
string16 query;
ListValue* root_list = NULL;
diff --git a/chrome/browser/autocomplete/search_provider.h b/chrome/browser/autocomplete/search_provider.h
index e8c07d5..cfff8a3 100644
--- a/chrome/browser/autocomplete/search_provider.h
+++ b/chrome/browser/autocomplete/search_provider.h
@@ -410,6 +410,11 @@ class SearchProvider : public AutocompleteProvider,
const TemplateURL* template_url,
const AutocompleteInput& input);
+ // Parses JSON response received from the provider, stripping XSSI
+ // protection if needed. Returns the parsed data if successful, NULL
+ // otherwise.
+ static scoped_ptr<base::Value> DeserializeJsonData(std::string json_data);
+
// Parses results from the suggest server and updates the appropriate suggest
// and navigation result lists, depending on whether |is_keyword| is true.
// Returns whether the appropriate result list members were updated.
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index bae74a7..6ae49e0 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -3748,9 +3748,35 @@ TEST_F(SearchProviderTest, PrefetchMetadataParsing) {
}
}
+TEST_F(SearchProviderTest, XSSIGuardedJSONParsing_InvalidResponse) {
+ ClearAllResults();
+
+ std::string input_str("abc");
+ QueryForInput(ASCIIToUTF16(input_str), false, false);
+
+ // Set up a default fetcher with provided results.
+ net::TestURLFetcher* fetcher =
+ test_factory_.GetFetcherByID(
+ SearchProvider::kDefaultProviderURLFetcherID);
+ ASSERT_TRUE(fetcher);
+ fetcher->set_response_code(200);
+ fetcher->SetResponseString("this is a bad non-json response");
+ fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+ RunTillProviderDone();
+
+ const ACMatches& matches = provider_->matches();
+
+ // Should have exactly one "search what you typed" match
+ ASSERT_TRUE(matches.size() == 1);
+ EXPECT_EQ(input_str, UTF16ToUTF8(matches[0].contents));
+ EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
+ matches[0].type);
+}
+
// A basic test that verifies that the XSSI guarded JSON response is parsed
// correctly.
-TEST_F(SearchProviderTest, XSSIGuardedJSONParsing) {
+TEST_F(SearchProviderTest, XSSIGuardedJSONParsing_ValidResponses) {
struct Match {
std::string contents;
AutocompleteMatchType::Type type;
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
index 07d7c2c..7207fd8 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider.cc
@@ -133,9 +133,7 @@ void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) {
source->GetStatus().is_success() && source->GetResponseCode() == 200;
if (request_succeeded) {
- JSONStringValueSerializer deserializer(json_data);
- deserializer.set_allow_trailing_comma(true);
- scoped_ptr<Value> data(deserializer.Deserialize(NULL, NULL));
+ scoped_ptr<Value> data(SearchProvider::DeserializeJsonData(json_data));
if (data.get())
ParseSuggestResults(*data.get());
}