Fix content verifier problem with content scripts (reland)
[chromium-blink-merge.git] / components / mime_util / mime_util.cc
blob49bf49d40f776dc76b8cef075f99513403346562
1 // Copyright 2015 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.
5 #include "components/mime_util/mime_util.h"
7 #include "base/containers/hash_tables.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/string_util.h"
10 #include "build/build_config.h"
12 #if !defined(OS_IOS)
13 // iOS doesn't use and must not depend on //media
14 #include "media/base/mime_util.h"
15 #endif
17 namespace mime_util {
19 namespace {
21 // Dictionary of cryptographic file mime types.
22 struct CertificateMimeTypeInfo {
23 const char* const mime_type;
24 net::CertificateMimeType cert_type;
27 const CertificateMimeTypeInfo kSupportedCertificateTypes[] = {
28 {"application/x-x509-user-cert", net::CERTIFICATE_MIME_TYPE_X509_USER_CERT},
29 #if defined(OS_ANDROID)
30 {"application/x-x509-ca-cert", net::CERTIFICATE_MIME_TYPE_X509_CA_CERT},
31 {"application/x-pkcs12", net::CERTIFICATE_MIME_TYPE_PKCS12_ARCHIVE},
32 #endif
35 // From WebKit's WebCore/platform/MIMETypeRegistry.cpp:
37 const char* const kSupportedImageTypes[] = {"image/jpeg",
38 "image/pjpeg",
39 "image/jpg",
40 "image/webp",
41 "image/png",
42 "image/gif",
43 "image/bmp",
44 "image/vnd.microsoft.icon", // ico
45 "image/x-icon", // ico
46 "image/x-xbitmap", // xbm
47 "image/x-png"};
49 // Mozilla 1.8 and WinIE 7 both accept text/javascript and text/ecmascript.
50 // Mozilla 1.8 accepts application/javascript, application/ecmascript, and
51 // application/x-javascript, but WinIE 7 doesn't.
52 // WinIE 7 accepts text/javascript1.1 - text/javascript1.3, text/jscript, and
53 // text/livescript, but Mozilla 1.8 doesn't.
54 // Mozilla 1.8 allows leading and trailing whitespace, but WinIE 7 doesn't.
55 // Mozilla 1.8 and WinIE 7 both accept the empty string, but neither accept a
56 // whitespace-only string.
57 // We want to accept all the values that either of these browsers accept, but
58 // not other values.
59 const char* const kSupportedJavascriptTypes[] = {"text/javascript",
60 "text/ecmascript",
61 "application/javascript",
62 "application/ecmascript",
63 "application/x-javascript",
64 "text/javascript1.1",
65 "text/javascript1.2",
66 "text/javascript1.3",
67 "text/jscript",
68 "text/livescript"};
70 // These types are excluded from the logic that allows all text/ types because
71 // while they are technically text, it's very unlikely that a user expects to
72 // see them rendered in text form.
73 static const char* const kUnsupportedTextTypes[] = {
74 "text/calendar",
75 "text/x-calendar",
76 "text/x-vcalendar",
77 "text/vcalendar",
78 "text/vcard",
79 "text/x-vcard",
80 "text/directory",
81 "text/ldif",
82 "text/qif",
83 "text/x-qif",
84 "text/x-csv",
85 "text/x-vcf",
86 "text/rtf",
87 "text/comma-separated-values",
88 "text/csv",
89 "text/tab-separated-values",
90 "text/tsv",
91 "text/ofx", // http://crbug.com/162238
92 "text/vnd.sun.j2me.app-descriptor" // http://crbug.com/176450
95 // Note:
96 // - does not include javascript types list (see supported_javascript_types)
97 // - does not include types starting with "text/" (see
98 // IsSupportedNonImageMimeType())
99 static const char* const kSupportedNonImageTypes[] = {
100 "image/svg+xml", // SVG is text-based XML, even though it has an image/
101 // type
102 "application/xml",
103 "application/atom+xml",
104 "application/rss+xml",
105 "application/xhtml+xml",
106 "application/json",
107 "multipart/related", // For MHTML support.
108 "multipart/x-mixed-replace"
109 // Note: ADDING a new type here will probably render it AS HTML. This can
110 // result in cross site scripting.
113 // Singleton utility class for mime types
114 class MimeUtil {
115 public:
116 bool IsSupportedImageMimeType(const std::string& mime_type) const;
117 bool IsSupportedNonImageMimeType(const std::string& mime_type) const;
118 bool IsUnsupportedTextMimeType(const std::string& mime_type) const;
119 bool IsSupportedJavascriptMimeType(const std::string& mime_type) const;
121 bool IsSupportedMimeType(const std::string& mime_type) const;
123 private:
124 friend struct base::DefaultLazyInstanceTraits<MimeUtil>;
126 using MimeTypes = base::hash_set<std::string>;
128 MimeUtil();
130 MimeTypes image_types_;
131 MimeTypes non_image_types_;
132 MimeTypes unsupported_text_types_;
133 MimeTypes javascript_types_;
135 DISALLOW_COPY_AND_ASSIGN(MimeUtil);
138 MimeUtil::MimeUtil() {
139 for (size_t i = 0; i < arraysize(kSupportedNonImageTypes); ++i)
140 non_image_types_.insert(kSupportedNonImageTypes[i]);
141 for (size_t i = 0; i < arraysize(kSupportedImageTypes); ++i)
142 image_types_.insert(kSupportedImageTypes[i]);
143 for (size_t i = 0; i < arraysize(kUnsupportedTextTypes); ++i)
144 unsupported_text_types_.insert(kUnsupportedTextTypes[i]);
145 for (size_t i = 0; i < arraysize(kSupportedJavascriptTypes); ++i) {
146 javascript_types_.insert(kSupportedJavascriptTypes[i]);
147 non_image_types_.insert(kSupportedJavascriptTypes[i]);
149 for (size_t i = 0; i < arraysize(kSupportedCertificateTypes); ++i)
150 non_image_types_.insert(kSupportedCertificateTypes[i].mime_type);
153 bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const {
154 return image_types_.find(base::StringToLowerASCII(mime_type)) !=
155 image_types_.end();
158 bool MimeUtil::IsSupportedNonImageMimeType(const std::string& mime_type) const {
159 return non_image_types_.find(base::StringToLowerASCII(mime_type)) !=
160 non_image_types_.end() ||
161 #if !defined(OS_IOS)
162 media::IsSupportedMediaMimeType(mime_type) ||
163 #endif
164 (base::StartsWith(mime_type, "text/",
165 base::CompareCase::INSENSITIVE_ASCII) &&
166 !IsUnsupportedTextMimeType(mime_type)) ||
167 (base::StartsWith(mime_type, "application/",
168 base::CompareCase::INSENSITIVE_ASCII) &&
169 net::MatchesMimeType("application/*+json", mime_type));
172 bool MimeUtil::IsUnsupportedTextMimeType(const std::string& mime_type) const {
173 return unsupported_text_types_.find(base::StringToLowerASCII(mime_type)) !=
174 unsupported_text_types_.end();
177 bool MimeUtil::IsSupportedJavascriptMimeType(
178 const std::string& mime_type) const {
179 return javascript_types_.find(mime_type) != javascript_types_.end();
182 bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const {
183 return (base::StartsWith(mime_type, "image/",
184 base::CompareCase::INSENSITIVE_ASCII) &&
185 IsSupportedImageMimeType(mime_type)) ||
186 IsSupportedNonImageMimeType(mime_type);
189 // This variable is Leaky because it is accessed from WorkerPool threads.
190 static base::LazyInstance<MimeUtil>::Leaky g_mime_util =
191 LAZY_INSTANCE_INITIALIZER;
193 } // namespace
195 bool IsSupportedImageMimeType(const std::string& mime_type) {
196 return g_mime_util.Get().IsSupportedImageMimeType(mime_type);
199 bool IsSupportedNonImageMimeType(const std::string& mime_type) {
200 return g_mime_util.Get().IsSupportedNonImageMimeType(mime_type);
203 bool IsUnsupportedTextMimeType(const std::string& mime_type) {
204 return g_mime_util.Get().IsUnsupportedTextMimeType(mime_type);
207 bool IsSupportedJavascriptMimeType(const std::string& mime_type) {
208 return g_mime_util.Get().IsSupportedJavascriptMimeType(mime_type);
211 bool IsSupportedCertificateMimeType(const std::string& mime_type) {
212 net::CertificateMimeType file_type =
213 GetCertificateMimeTypeForMimeType(mime_type);
214 return file_type != net::CERTIFICATE_MIME_TYPE_UNKNOWN;
217 bool IsSupportedMimeType(const std::string& mime_type) {
218 return g_mime_util.Get().IsSupportedMimeType(mime_type);
221 net::CertificateMimeType GetCertificateMimeTypeForMimeType(
222 const std::string& mime_type) {
223 // Don't create a map, there is only one entry in the table,
224 // except on Android.
225 for (size_t i = 0; i < arraysize(kSupportedCertificateTypes); ++i) {
226 if (base::EqualsCaseInsensitiveASCII(
227 mime_type, kSupportedCertificateTypes[i].mime_type)) {
228 return kSupportedCertificateTypes[i].cert_type;
232 return net::CERTIFICATE_MIME_TYPE_UNKNOWN;
235 } // namespace mime_util