1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/search_engines/template_url_data_util.h"
6 
7 #include <string>
8 
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_piece.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "components/search_engines/default_search_manager.h"
14 #include "components/search_engines/prepopulated_engines.h"
15 #include "components/search_engines/template_url_data.h"
16 #include "url/gurl.h"
17 
18 namespace {
19 
20 // Converts the C-style string `str` to a base::StringPiece making sure to avoid
21 // dereferencing nullptrs.
ToStringPiece(const char * str)22 base::StringPiece ToStringPiece(const char* str) {
23   return str ? base::StringPiece(str) : base::StringPiece();
24 }
25 
26 }  // namespace
27 
TemplateURLDataFromDictionary(const base::DictionaryValue & dict)28 std::unique_ptr<TemplateURLData> TemplateURLDataFromDictionary(
29     const base::DictionaryValue& dict) {
30   std::string search_url;
31   base::string16 keyword;
32   base::string16 short_name;
33   dict.GetString(DefaultSearchManager::kURL, &search_url);
34   dict.GetString(DefaultSearchManager::kKeyword, &keyword);
35   dict.GetString(DefaultSearchManager::kShortName, &short_name);
36   // Check required TemplateURLData fields first.
37   if (search_url.empty() || keyword.empty() || short_name.empty())
38     return std::unique_ptr<TemplateURLData>();
39 
40   auto result = std::make_unique<TemplateURLData>();
41   result->SetKeyword(keyword);
42   result->SetURL(search_url);
43 
44   std::string id;
45   dict.GetString(DefaultSearchManager::kID, &id);
46   base::StringToInt64(id, &result->id);
47 
48   result->SetShortName(short_name);
49   dict.GetInteger(DefaultSearchManager::kPrepopulateID,
50                   &result->prepopulate_id);
51   dict.GetString(DefaultSearchManager::kSyncGUID, &result->sync_guid);
52   dict.GetString(DefaultSearchManager::kSuggestionsURL,
53                  &result->suggestions_url);
54 
55   dict.GetString(DefaultSearchManager::kImageURL, &result->image_url);
56   dict.GetString(DefaultSearchManager::kNewTabURL, &result->new_tab_url);
57   dict.GetString(DefaultSearchManager::kContextualSearchURL,
58                  &result->contextual_search_url);
59   std::string favicon_url;
60   std::string originating_url;
61   std::string logo_url;
62   std::string doodle_url;
63   dict.GetString(DefaultSearchManager::kFaviconURL, &favicon_url);
64   dict.GetString(DefaultSearchManager::kOriginatingURL, &originating_url);
65   dict.GetString(DefaultSearchManager::kLogoURL, &logo_url);
66   dict.GetString(DefaultSearchManager::kDoodleURL, &doodle_url);
67   result->favicon_url = GURL(favicon_url);
68   result->originating_url = GURL(originating_url);
69   result->logo_url = GURL(logo_url);
70   result->doodle_url = GURL(doodle_url);
71 
72   dict.GetString(DefaultSearchManager::kSearchURLPostParams,
73                  &result->search_url_post_params);
74   dict.GetString(DefaultSearchManager::kSuggestionsURLPostParams,
75                  &result->suggestions_url_post_params);
76   dict.GetString(DefaultSearchManager::kImageURLPostParams,
77                  &result->image_url_post_params);
78   dict.GetBoolean(DefaultSearchManager::kSafeForAutoReplace,
79                   &result->safe_for_autoreplace);
80 
81   std::string date_created_str;
82   std::string last_modified_str;
83   std::string last_visited_str;
84   dict.GetString(DefaultSearchManager::kDateCreated, &date_created_str);
85   dict.GetString(DefaultSearchManager::kLastModified, &last_modified_str);
86   dict.GetString(DefaultSearchManager::kLastVisited, &last_visited_str);
87 
88   int64_t date_created = 0;
89   if (base::StringToInt64(date_created_str, &date_created))
90     result->date_created = base::Time::FromInternalValue(date_created);
91 
92   int64_t last_modified = 0;
93   if (base::StringToInt64(last_modified_str, &last_modified))
94     result->last_modified = base::Time::FromInternalValue(last_modified);
95 
96   int64_t last_visited = 0;
97   if (base::StringToInt64(last_visited_str, &last_visited))
98     result->last_visited = base::Time::FromInternalValue(last_visited);
99 
100   dict.GetInteger(DefaultSearchManager::kUsageCount, &result->usage_count);
101 
102   const base::ListValue* alternate_urls = nullptr;
103   if (dict.GetList(DefaultSearchManager::kAlternateURLs, &alternate_urls)) {
104     for (const auto& it : *alternate_urls) {
105       std::string alternate_url;
106       if (it.GetAsString(&alternate_url))
107         result->alternate_urls.push_back(std::move(alternate_url));
108     }
109   }
110 
111   const base::ListValue* encodings = nullptr;
112   if (dict.GetList(DefaultSearchManager::kInputEncodings, &encodings)) {
113     for (const auto& it : *encodings) {
114       std::string encoding;
115       if (it.GetAsString(&encoding))
116         result->input_encodings.push_back(std::move(encoding));
117     }
118   }
119 
120   dict.GetBoolean(DefaultSearchManager::kCreatedByPolicy,
121                   &result->created_by_policy);
122   dict.GetBoolean(DefaultSearchManager::kCreatedFromPlayAPI,
123                   &result->created_from_play_api);
124   return result;
125 }
126 
TemplateURLDataToDictionary(const TemplateURLData & data)127 std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
128     const TemplateURLData& data) {
129   auto url_dict = std::make_unique<base::DictionaryValue>();
130   url_dict->SetString(DefaultSearchManager::kID, base::NumberToString(data.id));
131   url_dict->SetString(DefaultSearchManager::kShortName, data.short_name());
132   url_dict->SetString(DefaultSearchManager::kKeyword, data.keyword());
133   url_dict->SetInteger(DefaultSearchManager::kPrepopulateID,
134                        data.prepopulate_id);
135   url_dict->SetString(DefaultSearchManager::kSyncGUID, data.sync_guid);
136 
137   url_dict->SetString(DefaultSearchManager::kURL, data.url());
138   url_dict->SetString(DefaultSearchManager::kSuggestionsURL,
139                       data.suggestions_url);
140   url_dict->SetString(DefaultSearchManager::kImageURL, data.image_url);
141   url_dict->SetString(DefaultSearchManager::kNewTabURL, data.new_tab_url);
142   url_dict->SetString(DefaultSearchManager::kContextualSearchURL,
143                       data.contextual_search_url);
144   url_dict->SetString(DefaultSearchManager::kFaviconURL,
145                       data.favicon_url.spec());
146   url_dict->SetString(DefaultSearchManager::kOriginatingURL,
147                       data.originating_url.spec());
148   url_dict->SetString(DefaultSearchManager::kLogoURL, data.logo_url.spec());
149   url_dict->SetString(DefaultSearchManager::kDoodleURL, data.doodle_url.spec());
150 
151   url_dict->SetString(DefaultSearchManager::kSearchURLPostParams,
152                       data.search_url_post_params);
153   url_dict->SetString(DefaultSearchManager::kSuggestionsURLPostParams,
154                       data.suggestions_url_post_params);
155   url_dict->SetString(DefaultSearchManager::kImageURLPostParams,
156                       data.image_url_post_params);
157 
158   url_dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace,
159                        data.safe_for_autoreplace);
160 
161   url_dict->SetString(
162       DefaultSearchManager::kDateCreated,
163       base::NumberToString(data.date_created.ToInternalValue()));
164   url_dict->SetString(
165       DefaultSearchManager::kLastModified,
166       base::NumberToString(data.last_modified.ToInternalValue()));
167   url_dict->SetString(
168       DefaultSearchManager::kLastVisited,
169       base::NumberToString(data.last_visited.ToInternalValue()));
170   url_dict->SetInteger(DefaultSearchManager::kUsageCount, data.usage_count);
171 
172   auto alternate_urls = std::make_unique<base::ListValue>();
173   for (const auto& alternate_url : data.alternate_urls)
174     alternate_urls->AppendString(alternate_url);
175 
176   url_dict->Set(DefaultSearchManager::kAlternateURLs,
177                 std::move(alternate_urls));
178 
179   auto encodings = std::make_unique<base::ListValue>();
180   for (const auto& input_encoding : data.input_encodings)
181     encodings->AppendString(input_encoding);
182   url_dict->Set(DefaultSearchManager::kInputEncodings, std::move(encodings));
183 
184   url_dict->SetBoolean(DefaultSearchManager::kCreatedByPolicy,
185                        data.created_by_policy);
186   url_dict->SetBoolean(DefaultSearchManager::kCreatedFromPlayAPI,
187                        data.created_from_play_api);
188   return url_dict;
189 }
190 
TemplateURLDataFromPrepopulatedEngine(const TemplateURLPrepopulateData::PrepopulatedEngine & engine)191 std::unique_ptr<TemplateURLData> TemplateURLDataFromPrepopulatedEngine(
192     const TemplateURLPrepopulateData::PrepopulatedEngine& engine) {
193   base::ListValue alternate_urls;
194   if (engine.alternate_urls) {
195     for (size_t i = 0; i < engine.alternate_urls_size; ++i)
196       alternate_urls.AppendString(std::string(engine.alternate_urls[i]));
197   }
198 
199   return std::make_unique<TemplateURLData>(
200       base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword),
201       ToStringPiece(engine.search_url), ToStringPiece(engine.suggest_url),
202       ToStringPiece(engine.image_url), ToStringPiece(engine.new_tab_url),
203       ToStringPiece(engine.contextual_search_url),
204       ToStringPiece(engine.logo_url), ToStringPiece(engine.doodle_url),
205       ToStringPiece(engine.search_url_post_params),
206       ToStringPiece(engine.suggest_url_post_params),
207       ToStringPiece(engine.image_url_post_params),
208       ToStringPiece(engine.favicon_url), ToStringPiece(engine.encoding),
209       alternate_urls, engine.id);
210 }
211 
TemplateURLDataFromOverrideDictionary(const base::DictionaryValue & engine)212 std::unique_ptr<TemplateURLData> TemplateURLDataFromOverrideDictionary(
213     const base::DictionaryValue& engine) {
214   base::string16 name;
215   base::string16 keyword;
216   std::string search_url;
217   std::string favicon_url;
218   std::string encoding;
219   int id = -1;
220   // The following fields are required for each search engine configuration.
221   if (engine.GetString("name", &name) && !name.empty() &&
222       engine.GetString("keyword", &keyword) && !keyword.empty() &&
223       engine.GetString("search_url", &search_url) && !search_url.empty() &&
224       engine.GetString("favicon_url", &favicon_url) && !favicon_url.empty() &&
225       engine.GetString("encoding", &encoding) && !encoding.empty() &&
226       engine.GetInteger("id", &id)) {
227     // These fields are optional.
228     std::string suggest_url;
229     std::string image_url;
230     std::string new_tab_url;
231     std::string contextual_search_url;
232     std::string logo_url;
233     std::string doodle_url;
234     std::string search_url_post_params;
235     std::string suggest_url_post_params;
236     std::string image_url_post_params;
237     base::ListValue empty_list;
238     const base::ListValue* alternate_urls = &empty_list;
239     engine.GetString("suggest_url", &suggest_url);
240     engine.GetString("image_url", &image_url);
241     engine.GetString("new_tab_url", &new_tab_url);
242     engine.GetString("contextual_search_url", &contextual_search_url);
243     engine.GetString("logo_url", &logo_url);
244     engine.GetString("doodle_url", &doodle_url);
245     engine.GetString("search_url_post_params", &search_url_post_params);
246     engine.GetString("suggest_url_post_params", &suggest_url_post_params);
247     engine.GetString("image_url_post_params", &image_url_post_params);
248     engine.GetList("alternate_urls", &alternate_urls);
249     return std::make_unique<TemplateURLData>(
250         name, keyword, search_url, suggest_url, image_url, new_tab_url,
251         contextual_search_url, logo_url, doodle_url, search_url_post_params,
252         suggest_url_post_params, image_url_post_params, favicon_url, encoding,
253         *alternate_urls, id);
254   }
255   return std::unique_ptr<TemplateURLData>();
256 }
257