• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 "chrome/browser/extensions/extension_warning_set.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/common/extensions/extension_set.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "extensions/common/extension.h"
13 #include "grit/chromium_strings.h"
14 #include "grit/generated_resources.h"
15 #include "net/base/escape.h"
16 #include "ui/base/l10n/l10n_util.h"
17 
18 using content::BrowserThread;
19 
20 namespace {
21 // Prefix for message parameters indicating that the parameter needs to
22 // be translated from an extension id to the extension name.
23 const char kTranslate[] = "TO_TRANSLATE:";
24 const size_t kMaxNumberOfParameters = 4;
25 }
26 
27 namespace extensions {
28 
29 //
30 // ExtensionWarning
31 //
32 
ExtensionWarning(WarningType type,const std::string & extension_id,int message_id,const std::vector<std::string> & message_parameters)33 ExtensionWarning::ExtensionWarning(
34     WarningType type,
35     const std::string& extension_id,
36     int message_id,
37     const std::vector<std::string>& message_parameters)
38     : type_(type),
39       extension_id_(extension_id),
40       message_id_(message_id),
41       message_parameters_(message_parameters) {
42   // These are invalid here because they do not have corresponding warning
43   // messages in the UI.
44   CHECK_NE(type, kInvalid);
45   CHECK_NE(type, kMaxWarningType);
46   CHECK_LE(message_parameters.size(), kMaxNumberOfParameters);
47 }
48 
ExtensionWarning(const ExtensionWarning & other)49 ExtensionWarning::ExtensionWarning(const ExtensionWarning& other)
50   : type_(other.type_),
51     extension_id_(other.extension_id_),
52     message_id_(other.message_id_),
53     message_parameters_(other.message_parameters_) {}
54 
~ExtensionWarning()55 ExtensionWarning::~ExtensionWarning() {
56 }
57 
operator =(const ExtensionWarning & other)58 ExtensionWarning& ExtensionWarning::operator=(const ExtensionWarning& other) {
59   type_ = other.type_;
60   extension_id_ = other.extension_id_;
61   message_id_ = other.message_id_;
62   message_parameters_ = other.message_parameters_;
63   return *this;
64 }
65 
66 // static
CreateNetworkDelayWarning(const std::string & extension_id)67 ExtensionWarning ExtensionWarning::CreateNetworkDelayWarning(
68     const std::string& extension_id) {
69   std::vector<std::string> message_parameters;
70   message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
71   return ExtensionWarning(
72       kNetworkDelay,
73       extension_id,
74       IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
75       message_parameters);
76 }
77 
78 // static
CreateNetworkConflictWarning(const std::string & extension_id)79 ExtensionWarning ExtensionWarning::CreateNetworkConflictWarning(
80     const std::string& extension_id) {
81   std::vector<std::string> message_parameters;
82   return ExtensionWarning(
83       kNetworkConflict,
84       extension_id,
85       IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT,
86       message_parameters);
87 }
88 
89 // static
CreateRedirectConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const GURL & attempted_redirect_url,const GURL & winning_redirect_url)90 ExtensionWarning ExtensionWarning::CreateRedirectConflictWarning(
91     const std::string& extension_id,
92     const std::string& winning_extension_id,
93     const GURL& attempted_redirect_url,
94     const GURL& winning_redirect_url) {
95   std::vector<std::string> message_parameters;
96   message_parameters.push_back(attempted_redirect_url.spec());
97   message_parameters.push_back(kTranslate + winning_extension_id);
98   message_parameters.push_back(winning_redirect_url.spec());
99   return ExtensionWarning(
100       kRedirectConflict,
101       extension_id,
102       IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT,
103       message_parameters);
104 }
105 
106 // static
CreateRequestHeaderConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const std::string & conflicting_header)107 ExtensionWarning ExtensionWarning::CreateRequestHeaderConflictWarning(
108     const std::string& extension_id,
109     const std::string& winning_extension_id,
110     const std::string& conflicting_header) {
111   std::vector<std::string> message_parameters;
112   message_parameters.push_back(conflicting_header);
113   message_parameters.push_back(kTranslate + winning_extension_id);
114   return ExtensionWarning(
115       kNetworkConflict,
116       extension_id,
117       IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT,
118       message_parameters);
119 }
120 
121 // static
CreateResponseHeaderConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const std::string & conflicting_header)122 ExtensionWarning ExtensionWarning::CreateResponseHeaderConflictWarning(
123     const std::string& extension_id,
124     const std::string& winning_extension_id,
125     const std::string& conflicting_header) {
126   std::vector<std::string> message_parameters;
127   message_parameters.push_back(conflicting_header);
128   message_parameters.push_back(kTranslate + winning_extension_id);
129   return ExtensionWarning(
130       kNetworkConflict,
131       extension_id,
132       IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT,
133       message_parameters);
134 }
135 
136 // static
CreateCredentialsConflictWarning(const std::string & extension_id,const std::string & winning_extension_id)137 ExtensionWarning ExtensionWarning::CreateCredentialsConflictWarning(
138     const std::string& extension_id,
139     const std::string& winning_extension_id) {
140   std::vector<std::string> message_parameters;
141   message_parameters.push_back(kTranslate + winning_extension_id);
142   return ExtensionWarning(
143       kNetworkConflict,
144       extension_id,
145       IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT,
146       message_parameters);
147 }
148 
149 // static
CreateRepeatedCacheFlushesWarning(const std::string & extension_id)150 ExtensionWarning ExtensionWarning::CreateRepeatedCacheFlushesWarning(
151     const std::string& extension_id) {
152   std::vector<std::string> message_parameters;
153   message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
154   return ExtensionWarning(
155       kRepeatedCacheFlushes,
156       extension_id,
157       IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
158       message_parameters);
159 }
160 
161 // static
CreateDownloadFilenameConflictWarning(const std::string & losing_extension_id,const std::string & winning_extension_id,const base::FilePath & losing_filename,const base::FilePath & winning_filename)162 ExtensionWarning ExtensionWarning::CreateDownloadFilenameConflictWarning(
163     const std::string& losing_extension_id,
164     const std::string& winning_extension_id,
165     const base::FilePath& losing_filename,
166     const base::FilePath& winning_filename) {
167   std::vector<std::string> message_parameters;
168   message_parameters.push_back(UTF16ToUTF8(losing_filename.LossyDisplayName()));
169   message_parameters.push_back(kTranslate + winning_extension_id);
170   message_parameters.push_back(UTF16ToUTF8(
171       winning_filename.LossyDisplayName()));
172   return ExtensionWarning(
173       kDownloadFilenameConflict,
174       losing_extension_id,
175       IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT,
176       message_parameters);
177 }
178 
GetLocalizedMessage(const ExtensionSet * extensions) const179 std::string ExtensionWarning::GetLocalizedMessage(
180     const ExtensionSet* extensions) const {
181   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182 
183   // These parameters may be unsafe (URLs and Extension names) and need
184   // to be HTML-escaped before being embedded in the UI. Also extension IDs
185   // are translated to full extension names.
186   std::vector<base::string16> final_parameters;
187   for (size_t i = 0; i < message_parameters_.size(); ++i) {
188     std::string message = message_parameters_[i];
189     if (StartsWithASCII(message, kTranslate, true)) {
190       std::string extension_id = message.substr(sizeof(kTranslate) - 1);
191       const extensions::Extension* extension =
192           extensions->GetByID(extension_id);
193       message = extension ? extension->name() : extension_id;
194     }
195     final_parameters.push_back(UTF8ToUTF16(net::EscapeForHTML(message)));
196   }
197 
198   COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements);
199   switch (final_parameters.size()) {
200     case 0:
201       return l10n_util::GetStringUTF8(message_id_);
202     case 1:
203       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]);
204     case 2:
205       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
206           final_parameters[1]);
207     case 3:
208       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
209           final_parameters[1], final_parameters[2]);
210     case 4:
211       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
212           final_parameters[1], final_parameters[2], final_parameters[3]);
213     default:
214       NOTREACHED();
215       return std::string();
216   }
217 }
218 
operator <(const ExtensionWarning & a,const ExtensionWarning & b)219 bool operator<(const ExtensionWarning& a, const ExtensionWarning& b) {
220   if (a.extension_id() != b.extension_id())
221     return a.extension_id() < b.extension_id();
222   return a.warning_type() < b.warning_type();
223 }
224 
225 }  // namespace extensions
226