1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include <stddef.h>
#include <string_view>
#include <unordered_set>
#include "base/containers/contains.h"
#include "base/containers/fixed_flat_set.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "media/media_buildflags.h"
#include "net/base/mime_util.h"
#include "third_party/blink/public/common/buildflags.h"
#if !BUILDFLAG(IS_IOS)
// iOS doesn't use and must not depend on //media
#include "media/base/mime_util.h"
#endif
namespace blink {
namespace {
// From WebKit's WebCore/platform/MIMETypeRegistry.cpp:
constexpr auto kSupportedImageTypes = base::MakeFixedFlatSet<std::string_view>({
"image/jpeg",
"image/pjpeg",
"image/jpg",
"image/webp",
"image/png",
"image/apng",
"image/gif",
"image/bmp",
"image/vnd.microsoft.icon", // ico
"image/x-icon", // ico
"image/x-xbitmap", // xbm
"image/x-png",
#if BUILDFLAG(ENABLE_AV1_DECODER)
"image/avif",
#endif
});
// Support every script type mentioned in the spec, as it notes that "User
// agents must recognize all JavaScript MIME types." See
// https://html.spec.whatwg.org/#javascript-mime-type.
constexpr auto kSupportedJavascriptTypes =
base::MakeFixedFlatSet<std::string_view>({
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
});
// These types are excluded from the logic that allows all text/ types because
// while they are technically text, it's very unlikely that a user expects to
// see them rendered in text form.
constexpr auto kUnsupportedTextTypes =
base::MakeFixedFlatSet<std::string_view>({
"text/calendar",
"text/x-calendar",
"text/x-vcalendar",
"text/vcalendar",
"text/vcard",
"text/x-vcard",
"text/directory",
"text/ldif",
"text/qif",
"text/x-qif",
"text/x-csv",
"text/x-vcf",
"text/rtf",
"text/comma-separated-values",
"text/csv",
"text/tab-separated-values",
"text/tsv",
"text/ofx", // https://crbug.com/162238
"text/vnd.sun.j2me.app-descriptor", // https://crbug.com/176450
"text/x-ms-iqy", // https://crbug.com/1054863
"text/x-ms-odc", // https://crbug.com/1054863
"text/x-ms-rqy", // https://crbug.com/1054863
"text/x-ms-contact" // https://crbug.com/1054863
});
// Note:
// - does not include javascript types list (see supported_javascript_types)
// - does not include types starting with "text/" (see
// IsSupportedNonImageMimeType())
constexpr auto kSupportedNonImageTypes =
base::MakeFixedFlatSet<std::string_view>({
"image/svg+xml", // SVG is text-based XML, even though it has an image/
// type
"application/xml", "application/atom+xml", "application/rss+xml",
"application/xhtml+xml", "application/json",
"message/rfc822", // For MHTML support.
"multipart/related", // For MHTML support.
"multipart/x-mixed-replace"
// Note: ADDING a new type here will probably render it AS HTML. This
// can result in cross site scripting.
});
} // namespace
bool IsSupportedImageMimeType(std::string_view mime_type) {
return kSupportedImageTypes.contains(base::ToLowerASCII(mime_type));
}
bool IsSupportedNonImageMimeType(std::string_view mime_type) {
std::string mime_lower = base::ToLowerASCII(mime_type);
return kSupportedNonImageTypes.contains(mime_lower) ||
kSupportedJavascriptTypes.contains(mime_lower) ||
#if !BUILDFLAG(IS_IOS)
media::IsSupportedMediaMimeType(mime_lower) ||
#endif
(mime_lower.starts_with("text/") &&
!kUnsupportedTextTypes.contains(mime_lower)) ||
(mime_lower.starts_with("application/") &&
net::MatchesMimeType("application/*+json", mime_lower));
}
bool IsUnsupportedTextMimeType(std::string_view mime_type) {
return kUnsupportedTextTypes.contains(base::ToLowerASCII(mime_type));
}
bool IsSupportedJavascriptMimeType(std::string_view mime_type) {
return kSupportedJavascriptTypes.contains(mime_type);
}
bool IsWasmMIMEType(std::string_view mime_type) {
return net::MatchesMimeType("application/wasm", mime_type);
}
// TODO(crbug.com/362282752): Allow non-application `*/*+json` MIME types.
// https://mimesniff.spec.whatwg.org/#json-mime-type
bool IsJSONMimeType(std::string_view mime_type) {
return net::MatchesMimeType("application/json", mime_type) ||
net::MatchesMimeType("text/json", mime_type) ||
net::MatchesMimeType("application/*+json", mime_type);
}
// TODO(crbug.com/362282752): Allow other `*/*+xml` MIME types.
// https://mimesniff.spec.whatwg.org/#xml-mime-type
bool IsXMLMimeType(std::string_view mime_type) {
return net::MatchesMimeType("text/xml", mime_type) ||
net::MatchesMimeType("application/xml", mime_type) ||
net::MatchesMimeType("application/*+xml", mime_type);
}
// From step 3 of
// https://mimesniff.spec.whatwg.org/#minimize-a-supported-mime-type.
bool IsSVGMimeType(std::string_view mime_type) {
return net::MatchesMimeType("image/svg+xml", mime_type);
}
bool IsSupportedMimeType(std::string_view mime_type) {
return (base::StartsWith(mime_type, "image/",
base::CompareCase::INSENSITIVE_ASCII) &&
IsSupportedImageMimeType(mime_type)) ||
IsSupportedNonImageMimeType(mime_type);
}
} // namespace blink
|