• 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 "extensions/browser/warning_set.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "extensions/common/extension.h"
12 #include "extensions/common/extension_set.h"
13 #include "extensions/common/extensions_client.h"
14 #include "extensions/strings/grit/extensions_strings.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 // Warning
31 //
32 
Warning(WarningType type,const std::string & extension_id,int message_id,const std::vector<std::string> & message_parameters)33 Warning::Warning(
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 
Warning(const Warning & other)49 Warning::Warning(const Warning& other)
50   : type_(other.type_),
51     extension_id_(other.extension_id_),
52     message_id_(other.message_id_),
53     message_parameters_(other.message_parameters_) {}
54 
~Warning()55 Warning::~Warning() {
56 }
57 
operator =(const Warning & other)58 Warning& Warning::operator=(const Warning& 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 Warning Warning::CreateNetworkDelayWarning(
68     const std::string& extension_id) {
69   std::vector<std::string> message_parameters;
70   message_parameters.push_back(ExtensionsClient::Get()->GetProductName());
71   return Warning(
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 Warning Warning::CreateNetworkConflictWarning(const std::string& extension_id) {
80   std::vector<std::string> message_parameters;
81   return Warning(
82       kNetworkConflict,
83       extension_id,
84       IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT,
85       message_parameters);
86 }
87 
88 // static
CreateRedirectConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const GURL & attempted_redirect_url,const GURL & winning_redirect_url)89 Warning Warning::CreateRedirectConflictWarning(
90     const std::string& extension_id,
91     const std::string& winning_extension_id,
92     const GURL& attempted_redirect_url,
93     const GURL& winning_redirect_url) {
94   std::vector<std::string> message_parameters;
95   message_parameters.push_back(attempted_redirect_url.spec());
96   message_parameters.push_back(kTranslate + winning_extension_id);
97   message_parameters.push_back(winning_redirect_url.spec());
98   return Warning(
99       kRedirectConflict,
100       extension_id,
101       IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT,
102       message_parameters);
103 }
104 
105 // static
CreateRequestHeaderConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const std::string & conflicting_header)106 Warning Warning::CreateRequestHeaderConflictWarning(
107     const std::string& extension_id,
108     const std::string& winning_extension_id,
109     const std::string& conflicting_header) {
110   std::vector<std::string> message_parameters;
111   message_parameters.push_back(conflicting_header);
112   message_parameters.push_back(kTranslate + winning_extension_id);
113   return Warning(
114       kNetworkConflict,
115       extension_id,
116       IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT,
117       message_parameters);
118 }
119 
120 // static
CreateResponseHeaderConflictWarning(const std::string & extension_id,const std::string & winning_extension_id,const std::string & conflicting_header)121 Warning Warning::CreateResponseHeaderConflictWarning(
122     const std::string& extension_id,
123     const std::string& winning_extension_id,
124     const std::string& conflicting_header) {
125   std::vector<std::string> message_parameters;
126   message_parameters.push_back(conflicting_header);
127   message_parameters.push_back(kTranslate + winning_extension_id);
128   return Warning(
129       kNetworkConflict,
130       extension_id,
131       IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT,
132       message_parameters);
133 }
134 
135 // static
CreateCredentialsConflictWarning(const std::string & extension_id,const std::string & winning_extension_id)136 Warning Warning::CreateCredentialsConflictWarning(
137     const std::string& extension_id,
138     const std::string& winning_extension_id) {
139   std::vector<std::string> message_parameters;
140   message_parameters.push_back(kTranslate + winning_extension_id);
141   return Warning(
142       kNetworkConflict,
143       extension_id,
144       IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT,
145       message_parameters);
146 }
147 
148 // static
CreateRepeatedCacheFlushesWarning(const std::string & extension_id)149 Warning Warning::CreateRepeatedCacheFlushesWarning(
150     const std::string& extension_id) {
151   std::vector<std::string> message_parameters;
152   message_parameters.push_back(ExtensionsClient::Get()->GetProductName());
153   return Warning(
154       kRepeatedCacheFlushes,
155       extension_id,
156       IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
157       message_parameters);
158 }
159 
160 // static
CreateDownloadFilenameConflictWarning(const std::string & losing_extension_id,const std::string & winning_extension_id,const base::FilePath & losing_filename,const base::FilePath & winning_filename)161 Warning Warning::CreateDownloadFilenameConflictWarning(
162     const std::string& losing_extension_id,
163     const std::string& winning_extension_id,
164     const base::FilePath& losing_filename,
165     const base::FilePath& winning_filename) {
166   std::vector<std::string> message_parameters;
167   message_parameters.push_back(base::UTF16ToUTF8(
168       losing_filename.LossyDisplayName()));
169   message_parameters.push_back(kTranslate + winning_extension_id);
170   message_parameters.push_back(base::UTF16ToUTF8(
171       winning_filename.LossyDisplayName()));
172   return Warning(
173       kDownloadFilenameConflict,
174       losing_extension_id,
175       IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT,
176       message_parameters);
177 }
178 
179 // static
CreateReloadTooFrequentWarning(const std::string & extension_id)180 Warning Warning::CreateReloadTooFrequentWarning(
181     const std::string& extension_id) {
182   std::vector<std::string> message_parameters;
183   return Warning(kReloadTooFrequent,
184                           extension_id,
185                           IDS_EXTENSION_WARNING_RELOAD_TOO_FREQUENT,
186                           message_parameters);
187 }
188 
GetLocalizedMessage(const ExtensionSet * extensions) const189 std::string Warning::GetLocalizedMessage(const ExtensionSet* extensions) const {
190   DCHECK_CURRENTLY_ON(BrowserThread::UI);
191 
192   // These parameters may be unsafe (URLs and Extension names) and need
193   // to be HTML-escaped before being embedded in the UI. Also extension IDs
194   // are translated to full extension names.
195   std::vector<base::string16> final_parameters;
196   for (size_t i = 0; i < message_parameters_.size(); ++i) {
197     std::string message = message_parameters_[i];
198     if (StartsWithASCII(message, kTranslate, true)) {
199       std::string extension_id = message.substr(sizeof(kTranslate) - 1);
200       const extensions::Extension* extension =
201           extensions->GetByID(extension_id);
202       message = extension ? extension->name() : extension_id;
203     }
204     final_parameters.push_back(base::UTF8ToUTF16(net::EscapeForHTML(message)));
205   }
206 
207   COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements);
208   switch (final_parameters.size()) {
209     case 0:
210       return l10n_util::GetStringUTF8(message_id_);
211     case 1:
212       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]);
213     case 2:
214       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
215           final_parameters[1]);
216     case 3:
217       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
218           final_parameters[1], final_parameters[2]);
219     case 4:
220       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
221           final_parameters[1], final_parameters[2], final_parameters[3]);
222     default:
223       NOTREACHED();
224       return std::string();
225   }
226 }
227 
operator <(const Warning & a,const Warning & b)228 bool operator<(const Warning& a, const Warning& b) {
229   if (a.extension_id() != b.extension_id())
230     return a.extension_id() < b.extension_id();
231   return a.warning_type() < b.warning_type();
232 }
233 
234 }  // namespace extensions
235