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 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 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 55 ExtensionWarning::~ExtensionWarning() { 56 } 57 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 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 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 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 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 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 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 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 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 179 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 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