| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/search_engines/template_url_parser.h" | 5 #include "components/search_engines/template_url_parser.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 // having to convert to wide, then do comparisons. | 27 // having to convert to wide, then do comparisons. |
| 28 | 28 |
| 29 // Defines for element names of the OSD document: | 29 // Defines for element names of the OSD document: |
| 30 const char kURLElement[] = "Url"; | 30 const char kURLElement[] = "Url"; |
| 31 const char kParamElement[] = "Param"; | 31 const char kParamElement[] = "Param"; |
| 32 const char kShortNameElement[] = "ShortName"; | 32 const char kShortNameElement[] = "ShortName"; |
| 33 const char kImageElement[] = "Image"; | 33 const char kImageElement[] = "Image"; |
| 34 const char kOpenSearchDescriptionElement[] = "OpenSearchDescription"; | 34 const char kOpenSearchDescriptionElement[] = "OpenSearchDescription"; |
| 35 const char kFirefoxSearchDescriptionElement[] = "SearchPlugin"; | 35 const char kFirefoxSearchDescriptionElement[] = "SearchPlugin"; |
| 36 const char kInputEncodingElement[] = "InputEncoding"; | 36 const char kInputEncodingElement[] = "InputEncoding"; |
| 37 const char kAliasElement[] = "Alias"; |
| 37 | 38 |
| 38 // Various XML attributes used. | 39 // Various XML attributes used. |
| 39 const char kURLTypeAttribute[] = "type"; | 40 const char kURLTypeAttribute[] = "type"; |
| 40 const char kURLTemplateAttribute[] = "template"; | 41 const char kURLTemplateAttribute[] = "template"; |
| 41 const char kImageTypeAttribute[] = "type"; | 42 const char kImageTypeAttribute[] = "type"; |
| 42 const char kImageWidthAttribute[] = "width"; | 43 const char kImageWidthAttribute[] = "width"; |
| 43 const char kImageHeightAttribute[] = "height"; | 44 const char kImageHeightAttribute[] = "height"; |
| 44 const char kParamNameAttribute[] = "name"; | 45 const char kParamNameAttribute[] = "name"; |
| 45 const char kParamValueAttribute[] = "value"; | 46 const char kParamValueAttribute[] = "value"; |
| 46 const char kParamMethodAttribute[] = "method"; | 47 const char kParamMethodAttribute[] = "method"; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 public: | 109 public: |
| 109 // Enum of the known element types. | 110 // Enum of the known element types. |
| 110 enum ElementType { | 111 enum ElementType { |
| 111 UNKNOWN, | 112 UNKNOWN, |
| 112 OPEN_SEARCH_DESCRIPTION, | 113 OPEN_SEARCH_DESCRIPTION, |
| 113 URL, | 114 URL, |
| 114 PARAM, | 115 PARAM, |
| 115 SHORT_NAME, | 116 SHORT_NAME, |
| 116 IMAGE, | 117 IMAGE, |
| 117 INPUT_ENCODING, | 118 INPUT_ENCODING, |
| 119 ALIAS, |
| 118 }; | 120 }; |
| 119 | 121 |
| 120 enum Method { | 122 enum Method { |
| 121 GET, | 123 GET, |
| 122 POST | 124 POST |
| 123 }; | 125 }; |
| 124 | 126 |
| 125 // Key/value of a Param node. | 127 // Key/value of a Param node. |
| 126 typedef std::pair<std::string, std::string> Param; | 128 typedef std::pair<std::string, std::string> Param; |
| 127 | 129 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 std::vector<Param> extra_params_; | 175 std::vector<Param> extra_params_; |
| 174 | 176 |
| 175 // The HTTP methods used. | 177 // The HTTP methods used. |
| 176 Method method_; | 178 Method method_; |
| 177 Method suggestion_method_; | 179 Method suggestion_method_; |
| 178 | 180 |
| 179 // If true, we are currently parsing a suggest URL, otherwise it is an HTML | 181 // If true, we are currently parsing a suggest URL, otherwise it is an HTML |
| 180 // search. Note that we don't need a stack as URL nodes cannot be nested. | 182 // search. Note that we don't need a stack as URL nodes cannot be nested. |
| 181 bool is_suggest_url_; | 183 bool is_suggest_url_; |
| 182 | 184 |
| 185 // If true, the user has set a keyword and we should use it. Otherwise, |
| 186 // we generate a keyword based on the URL. |
| 187 bool has_custom_keyword_; |
| 188 |
| 183 // Whether we should derive the image from the URL (when images are data | 189 // Whether we should derive the image from the URL (when images are data |
| 184 // URLs). | 190 // URLs). |
| 185 bool derive_image_from_url_; | 191 bool derive_image_from_url_; |
| 186 | 192 |
| 187 DISALLOW_COPY_AND_ASSIGN(TemplateURLParsingContext); | 193 DISALLOW_COPY_AND_ASSIGN(TemplateURLParsingContext); |
| 188 }; | 194 }; |
| 189 | 195 |
| 190 // static | 196 // static |
| 191 TemplateURLParsingContext::ElementNameToElementTypeMap* | 197 TemplateURLParsingContext::ElementNameToElementTypeMap* |
| 192 TemplateURLParsingContext::kElementNameToElementTypeMap = NULL; | 198 TemplateURLParsingContext::kElementNameToElementTypeMap = NULL; |
| 193 | 199 |
| 194 TemplateURLParsingContext::TemplateURLParsingContext( | 200 TemplateURLParsingContext::TemplateURLParsingContext( |
| 195 TemplateURLParser::ParameterFilter* parameter_filter) | 201 TemplateURLParser::ParameterFilter* parameter_filter) |
| 196 : image_is_valid_for_favicon_(false), | 202 : image_is_valid_for_favicon_(false), |
| 197 parameter_filter_(parameter_filter), | 203 parameter_filter_(parameter_filter), |
| 198 method_(GET), | 204 method_(GET), |
| 199 suggestion_method_(GET), | 205 suggestion_method_(GET), |
| 200 is_suggest_url_(false), | 206 is_suggest_url_(false), |
| 207 has_custom_keyword_(false), |
| 201 derive_image_from_url_(false) { | 208 derive_image_from_url_(false) { |
| 202 if (kElementNameToElementTypeMap == NULL) | 209 if (kElementNameToElementTypeMap == NULL) |
| 203 InitMapping(); | 210 InitMapping(); |
| 204 } | 211 } |
| 205 | 212 |
| 206 // static | 213 // static |
| 207 void TemplateURLParsingContext::StartElementImpl(void* ctx, | 214 void TemplateURLParsingContext::StartElementImpl(void* ctx, |
| 208 const xmlChar* name, | 215 const xmlChar* name, |
| 209 const xmlChar** atts) { | 216 const xmlChar** atts) { |
| 210 // Remove the namespace from |name|, ex: os:Url -> Url. | 217 // Remove the namespace from |name|, ex: os:Url -> Url. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 233 break; | 240 break; |
| 234 } | 241 } |
| 235 context->string_.clear(); | 242 context->string_.clear(); |
| 236 } | 243 } |
| 237 | 244 |
| 238 // static | 245 // static |
| 239 void TemplateURLParsingContext::EndElementImpl(void* ctx, const xmlChar* name) { | 246 void TemplateURLParsingContext::EndElementImpl(void* ctx, const xmlChar* name) { |
| 240 TemplateURLParsingContext* context = | 247 TemplateURLParsingContext* context = |
| 241 reinterpret_cast<TemplateURLParsingContext*>(ctx); | 248 reinterpret_cast<TemplateURLParsingContext*>(ctx); |
| 242 switch (context->GetKnownType()) { | 249 switch (context->GetKnownType()) { |
| 250 case TemplateURLParsingContext::URL: |
| 251 context->ProcessURLParams(); |
| 252 break; |
| 243 case TemplateURLParsingContext::SHORT_NAME: | 253 case TemplateURLParsingContext::SHORT_NAME: |
| 244 context->data_.short_name = context->string_; | 254 context->data_.short_name = context->string_; |
| 245 break; | 255 break; |
| 246 case TemplateURLParsingContext::IMAGE: { | 256 case TemplateURLParsingContext::IMAGE: { |
| 247 GURL image_url(base::UTF16ToUTF8(context->string_)); | 257 GURL image_url(base::UTF16ToUTF8(context->string_)); |
| 248 if (image_url.SchemeIs(url::kDataScheme)) { | 258 if (image_url.SchemeIs(url::kDataScheme)) { |
| 249 // TODO (jcampan): bug 1169256: when dealing with data URL, we need to | 259 // TODO (jcampan): bug 1169256: when dealing with data URL, we need to |
| 250 // decode the data URL in the renderer. For now, we'll just point to the | 260 // decode the data URL in the renderer. For now, we'll just point to the |
| 251 // favicon from the URL. | 261 // favicon from the URL. |
| 252 context->derive_image_from_url_ = true; | 262 context->derive_image_from_url_ = true; |
| 253 } else if (context->image_is_valid_for_favicon_ && image_url.is_valid() && | 263 } else if (context->image_is_valid_for_favicon_ && image_url.is_valid() && |
| 254 (image_url.SchemeIs(url::kHttpScheme) || | 264 (image_url.SchemeIs(url::kHttpScheme) || |
| 255 image_url.SchemeIs(url::kHttpsScheme))) { | 265 image_url.SchemeIs(url::kHttpsScheme))) { |
| 256 context->data_.favicon_url = image_url; | 266 context->data_.favicon_url = image_url; |
| 257 } | 267 } |
| 258 context->image_is_valid_for_favicon_ = false; | 268 context->image_is_valid_for_favicon_ = false; |
| 259 break; | 269 break; |
| 260 } | 270 } |
| 261 case TemplateURLParsingContext::INPUT_ENCODING: { | 271 case TemplateURLParsingContext::INPUT_ENCODING: { |
| 262 std::string input_encoding = base::UTF16ToASCII(context->string_); | 272 std::string input_encoding = base::UTF16ToASCII(context->string_); |
| 263 if (IsValidEncodingString(input_encoding)) | 273 if (IsValidEncodingString(input_encoding)) |
| 264 context->data_.input_encodings.push_back(input_encoding); | 274 context->data_.input_encodings.push_back(input_encoding); |
| 265 break; | 275 break; |
| 266 } | 276 } |
| 267 case TemplateURLParsingContext::URL: | 277 case TemplateURLParsingContext::ALIAS: { |
| 268 context->ProcessURLParams(); | 278 context->data_.SetKeyword(context->string_); |
| 279 context->has_custom_keyword_ = true; |
| 269 break; | 280 break; |
| 281 } |
| 270 default: | 282 default: |
| 271 break; | 283 break; |
| 272 } | 284 } |
| 273 context->string_.clear(); | 285 context->string_.clear(); |
| 274 context->elements_.pop_back(); | 286 context->elements_.pop_back(); |
| 275 } | 287 } |
| 276 | 288 |
| 277 // static | 289 // static |
| 278 void TemplateURLParsingContext::CharactersImpl(void* ctx, | 290 void TemplateURLParsingContext::CharactersImpl(void* ctx, |
| 279 const xmlChar* ch, | 291 const xmlChar* ch, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 291 return NULL; | 303 return NULL; |
| 292 if (suggestion_method_ == TemplateURLParsingContext::POST) | 304 if (suggestion_method_ == TemplateURLParsingContext::POST) |
| 293 data_.suggestions_url.clear(); | 305 data_.suggestions_url.clear(); |
| 294 | 306 |
| 295 // If the image was a data URL, use the favicon from the search URL instead. | 307 // If the image was a data URL, use the favicon from the search URL instead. |
| 296 // (see the TODO in EndElementImpl()). | 308 // (see the TODO in EndElementImpl()). |
| 297 GURL search_url(data_.url()); | 309 GURL search_url(data_.url()); |
| 298 if (derive_image_from_url_ && data_.favicon_url.is_empty()) | 310 if (derive_image_from_url_ && data_.favicon_url.is_empty()) |
| 299 data_.favicon_url = TemplateURL::GenerateFaviconURL(search_url); | 311 data_.favicon_url = TemplateURL::GenerateFaviconURL(search_url); |
| 300 | 312 |
| 301 data_.SetKeyword(TemplateURL::GenerateKeyword(search_url)); | 313 // Generate a keyword for this search engine if a custom one was not present |
| 314 // in the imported data. |
| 315 if (!has_custom_keyword_) |
| 316 data_.SetKeyword(TemplateURL::GenerateKeyword(search_url)); |
| 317 |
| 302 data_.show_in_default_list = show_in_default_list; | 318 data_.show_in_default_list = show_in_default_list; |
| 303 | 319 |
| 304 // Bail if the search URL is empty or if either TemplateURLRef is invalid. | 320 // Bail if the search URL is empty or if either TemplateURLRef is invalid. |
| 305 scoped_ptr<TemplateURL> template_url(new TemplateURL(data_)); | 321 scoped_ptr<TemplateURL> template_url(new TemplateURL(data_)); |
| 306 if (template_url->url().empty() || | 322 if (template_url->url().empty() || |
| 307 !template_url->url_ref().IsValid(search_terms_data) || | 323 !template_url->url_ref().IsValid(search_terms_data) || |
| 308 (!template_url->suggestions_url().empty() && | 324 (!template_url->suggestions_url().empty() && |
| 309 !template_url->suggestions_url_ref().IsValid(search_terms_data))) { | 325 !template_url->suggestions_url_ref().IsValid(search_terms_data))) { |
| 310 return NULL; | 326 return NULL; |
| 311 } | 327 } |
| 312 | 328 |
| 313 return template_url.release(); | 329 return template_url.release(); |
| 314 } | 330 } |
| 315 | 331 |
| 316 // static | 332 // static |
| 317 void TemplateURLParsingContext::InitMapping() { | 333 void TemplateURLParsingContext::InitMapping() { |
| 318 kElementNameToElementTypeMap = new std::map<std::string, ElementType>; | 334 kElementNameToElementTypeMap = new std::map<std::string, ElementType>; |
| 319 (*kElementNameToElementTypeMap)[kURLElement] = URL; | 335 (*kElementNameToElementTypeMap)[kURLElement] = URL; |
| 320 (*kElementNameToElementTypeMap)[kParamElement] = PARAM; | 336 (*kElementNameToElementTypeMap)[kParamElement] = PARAM; |
| 321 (*kElementNameToElementTypeMap)[kShortNameElement] = SHORT_NAME; | 337 (*kElementNameToElementTypeMap)[kShortNameElement] = SHORT_NAME; |
| 322 (*kElementNameToElementTypeMap)[kImageElement] = IMAGE; | 338 (*kElementNameToElementTypeMap)[kImageElement] = IMAGE; |
| 323 (*kElementNameToElementTypeMap)[kOpenSearchDescriptionElement] = | 339 (*kElementNameToElementTypeMap)[kOpenSearchDescriptionElement] = |
| 324 OPEN_SEARCH_DESCRIPTION; | 340 OPEN_SEARCH_DESCRIPTION; |
| 325 (*kElementNameToElementTypeMap)[kFirefoxSearchDescriptionElement] = | 341 (*kElementNameToElementTypeMap)[kFirefoxSearchDescriptionElement] = |
| 326 OPEN_SEARCH_DESCRIPTION; | 342 OPEN_SEARCH_DESCRIPTION; |
| 327 (*kElementNameToElementTypeMap)[kInputEncodingElement] = INPUT_ENCODING; | 343 (*kElementNameToElementTypeMap)[kInputEncodingElement] = INPUT_ENCODING; |
| 344 (*kElementNameToElementTypeMap)[kAliasElement] = ALIAS; |
| 328 } | 345 } |
| 329 | 346 |
| 330 void TemplateURLParsingContext::ParseURL(const xmlChar** atts) { | 347 void TemplateURLParsingContext::ParseURL(const xmlChar** atts) { |
| 331 if (!atts) | 348 if (!atts) |
| 332 return; | 349 return; |
| 333 | 350 |
| 334 std::string template_url; | 351 std::string template_url; |
| 335 bool is_post = false; | 352 bool is_post = false; |
| 336 bool is_html_url = false; | 353 bool is_html_url = false; |
| 337 bool is_suggest_url = false; | 354 bool is_suggest_url = false; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 sax_handler.startElement = &TemplateURLParsingContext::StartElementImpl; | 501 sax_handler.startElement = &TemplateURLParsingContext::StartElementImpl; |
| 485 sax_handler.endElement = &TemplateURLParsingContext::EndElementImpl; | 502 sax_handler.endElement = &TemplateURLParsingContext::EndElementImpl; |
| 486 sax_handler.characters = &TemplateURLParsingContext::CharactersImpl; | 503 sax_handler.characters = &TemplateURLParsingContext::CharactersImpl; |
| 487 int error = xmlSAXUserParseMemory(&sax_handler, &context, data, | 504 int error = xmlSAXUserParseMemory(&sax_handler, &context, data, |
| 488 static_cast<int>(length)); | 505 static_cast<int>(length)); |
| 489 xmlSubstituteEntitiesDefault(last_sub_entities_value); | 506 xmlSubstituteEntitiesDefault(last_sub_entities_value); |
| 490 | 507 |
| 491 return error ? | 508 return error ? |
| 492 NULL : context.GetTemplateURL(search_terms_data, show_in_default_list); | 509 NULL : context.GetTemplateURL(search_terms_data, show_in_default_list); |
| 493 } | 510 } |
| OLD | NEW |