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

Side by Side Diff: chrome/browser/autocomplete/search_provider.cc

Issue 45863006: Parse out XSSI guards in Suggestion JSON response (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ready for review Created 7 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/autocomplete/search_provider_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/autocomplete/search_provider.h" 5 #include "chrome/browser/autocomplete/search_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 593
594 if (clear_cached_results) 594 if (clear_cached_results)
595 ClearAllResults(); 595 ClearAllResults();
596 } 596 }
597 597
598 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { 598 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) {
599 DCHECK(!done_); 599 DCHECK(!done_);
600 suggest_results_pending_--; 600 suggest_results_pending_--;
601 LogOmniboxSuggestRequest(REPLY_RECEIVED); 601 LogOmniboxSuggestRequest(REPLY_RECEIVED);
602 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative. 602 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative.
603 const net::HttpResponseHeaders* const response_headers =
604 source->GetResponseHeaders();
605 std::string json_data;
606 source->GetResponseAsString(&json_data);
607 // JSON is supposed to be UTF-8, but some suggest service providers send JSON
608 // files in non-UTF-8 encodings. The actual encoding is usually specified in
609 // the Content-Type header field.
610 if (response_headers) {
611 std::string charset;
612 if (response_headers->GetCharset(&charset)) {
613 string16 data_16;
614 // TODO(jungshik): Switch to CodePageToUTF8 after it's added.
615 if (base::CodepageToUTF16(json_data, charset.c_str(),
616 base::OnStringConversionError::FAIL,
617 &data_16))
618 json_data = UTF16ToUTF8(data_16);
619 }
620 }
621 603
622 const bool is_keyword = (source == keyword_fetcher_.get()); 604 const bool is_keyword = (source == keyword_fetcher_.get());
623 // Ensure the request succeeded and that the provider used is still available. 605 // Ensure the request succeeded and that the provider used is still available.
624 // A verbatim match cannot be generated without this provider, causing errors. 606 // A verbatim match cannot be generated without this provider, causing errors.
625 const bool request_succeeded = 607 const bool request_succeeded =
626 source->GetStatus().is_success() && (source->GetResponseCode() == 200) && 608 source->GetStatus().is_success() && (source->GetResponseCode() == 200) &&
627 (is_keyword ? 609 (is_keyword ?
628 providers_.GetKeywordProviderURL() : 610 providers_.GetKeywordProviderURL() :
629 providers_.GetDefaultProviderURL()); 611 providers_.GetDefaultProviderURL());
630 612
(...skipping 10 matching lines...) Expand all
641 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime", 623 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime",
642 elapsed_time); 624 elapsed_time);
643 } else { 625 } else {
644 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime", 626 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime",
645 elapsed_time); 627 elapsed_time);
646 } 628 }
647 } 629 }
648 630
649 bool results_updated = false; 631 bool results_updated = false;
650 if (request_succeeded) { 632 if (request_succeeded) {
651 JSONStringValueSerializer deserializer(json_data); 633 const net::HttpResponseHeaders* const response_headers =
652 deserializer.set_allow_trailing_comma(true); 634 source->GetResponseHeaders();
653 scoped_ptr<Value> data(deserializer.Deserialize(NULL, NULL)); 635 std::string json_data;
654 results_updated = data.get() && ParseSuggestResults(data.get(), is_keyword); 636 source->GetResponseAsString(&json_data);
637 // JSON is supposed to be UTF-8, but some suggest service providers send
638 // JSON files in non-UTF-8 encodings. The actual encoding is usually
639 // specified in the Content-Type header field.
640 if (response_headers) {
641 std::string charset;
642 if (response_headers->GetCharset(&charset)) {
643 string16 data_16;
644 // TODO(jungshik): Switch to CodePageToUTF8 after it's added.
645 if (base::CodepageToUTF16(json_data, charset.c_str(),
646 base::OnStringConversionError::FAIL,
647 &data_16))
648 json_data = UTF16ToUTF8(data_16);
649 }
650 }
651
652 int error_code = 0;
653 while (true) {
Peter Kasting 2013/10/29 18:45:49 This can infinite loop. If we find the first '[',
Maria 2013/10/29 18:55:45 I don't think it's likely that XSSI guard would ch
Anuj 2013/10/29 18:58:05 Please see the test cases - Hypothetically XSSI gu
Anuj 2013/10/29 19:03:35 XSSI guard may not change. But looking for respons
654 // The JSON response should be an array.
655 size_t response_start_index = json_data.find("[");
656
657 if (response_start_index == std::string::npos)
658 break;
659
660 // Remove any XSSI guards to allow for JSON parsing.
661 if (response_start_index > 0)
662 json_data.erase(0, response_start_index - 1);
663
664 JSONStringValueSerializer deserializer(json_data);
665 deserializer.set_allow_trailing_comma(true);
666 scoped_ptr<Value> data(deserializer.Deserialize(&error_code, NULL));
667 if (error_code == 0) {
668 results_updated = data.get() &&
669 ParseSuggestResults(data.get(), is_keyword);
670 break;
671 }
672 }
655 } 673 }
656 674
657 UpdateMatches(); 675 UpdateMatches();
658 if (done_ || results_updated) 676 if (done_ || results_updated)
659 listener_->OnProviderUpdate(results_updated); 677 listener_->OnProviderUpdate(results_updated);
660 } 678 }
661 679
662 void SearchProvider::Run() { 680 void SearchProvider::Run() {
663 // Start a new request with the current input. 681 // Start a new request with the current input.
664 suggest_results_pending_ = 0; 682 suggest_results_pending_ = 0;
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 it->set_relevance(max_query_relevance); 1781 it->set_relevance(max_query_relevance);
1764 it->set_relevance_from_server(relevance_from_server); 1782 it->set_relevance_from_server(relevance_from_server);
1765 } 1783 }
1766 } 1784 }
1767 1785
1768 void SearchProvider::UpdateDone() { 1786 void SearchProvider::UpdateDone() {
1769 // We're done when the timer isn't running, there are no suggest queries 1787 // We're done when the timer isn't running, there are no suggest queries
1770 // pending, and we're not waiting on Instant. 1788 // pending, and we're not waiting on Instant.
1771 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); 1789 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0);
1772 } 1790 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/autocomplete/search_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698