Bug 1847358 part 3: add a fullMimeType attribute to nsIBaseChannel and use it to make our Data URI content-type header parsing standards-compliant for XHR and Fetch; r=dlrobertson,necko-reviewers,jesup

Differential Revision: https://phabricator.services.mozilla.com/D203380
This commit is contained in:
Thomas Wisniewski 2024-03-04 21:34:27 +00:00
Родитель 7c31f0e0ae
Коммит 64e64191cb
13 изменённых файлов: 143 добавлений и 112 удалений

Просмотреть файл

@ -267,7 +267,7 @@ class MOZ_STACK_CLASS FormDataParser {
}
// Determine boundary from mimetype.
UniquePtr<CMimeType> parsed = CMimeType::Parse(mMixedCaseMimeType);
RefPtr<CMimeType> parsed = CMimeType::Parse(mMixedCaseMimeType);
if (!parsed) {
return false;
}

Просмотреть файл

@ -9,8 +9,8 @@
#include "nsUnicharUtils.h"
template <typename char_type>
/* static */ mozilla::UniquePtr<TMimeType<char_type>>
TMimeType<char_type>::Parse(const nsTSubstring<char_type>& aMimeType) {
/* static */ RefPtr<TMimeType<char_type>> TMimeType<char_type>::Parse(
const nsTSubstring<char_type>& aMimeType) {
// See https://mimesniff.spec.whatwg.org/#parsing-a-mime-type
// Steps 1-2
@ -85,8 +85,8 @@ TMimeType<char_type>::Parse(const nsTSubstring<char_type>& aMimeType) {
for (const char_type* c = subtypeStart; c < subtypeEnd; ++c) {
subtype.Append(ToLowerCaseASCII(*c));
}
mozilla::UniquePtr<TMimeType<char_type>> mimeType(
mozilla::MakeUnique<TMimeType<char_type>>(type, subtype));
RefPtr<TMimeType<char_type>> mimeType =
new TMimeType<char_type>(type, subtype);
// Step 11
while (pos < end) {
@ -274,7 +274,7 @@ template <typename char_type>
static char_type kCHARSET[] = {'c', 'h', 'a', 'r', 's', 'e', 't'};
static nsTDependentSubstring<char_type> kCharset(kCHARSET, 7);
mozilla::UniquePtr<TMimeType<char_type>> parsed;
RefPtr<TMimeType<char_type>> parsed;
nsTAutoString<char_type> prevContentType;
nsTAutoString<char_type> prevCharset;
@ -398,9 +398,9 @@ void TMimeType<char_type>::SetParameterValue(
});
}
template mozilla::UniquePtr<TMimeType<char16_t>> TMimeType<char16_t>::Parse(
template RefPtr<TMimeType<char16_t>> TMimeType<char16_t>::Parse(
const nsTSubstring<char16_t>& aMimeType);
template mozilla::UniquePtr<TMimeType<char>> TMimeType<char>::Parse(
template RefPtr<TMimeType<char>> TMimeType<char>::Parse(
const nsTSubstring<char>& aMimeType);
template bool TMimeType<char16_t>::Parse(
const nsTSubstring<char16_t>& aMimeType,

Просмотреть файл

@ -8,7 +8,6 @@
#define mozilla_dom_MimeType_h
#include "mozilla/TextUtils.h"
#include "mozilla/UniquePtr.h"
#include "nsTHashMap.h"
#include "nsTArray.h"
@ -26,6 +25,8 @@ struct HashKeyType<char> {
template <typename char_type>
class TMimeType final {
private:
~TMimeType() = default;
class ParameterValue : public nsTString<char_type> {
public:
bool mRequiresQuoting;
@ -48,8 +49,8 @@ class TMimeType final {
const nsTSubstring<char_type>& aSubtype)
: mType(aType), mSubtype(aSubtype) {}
static mozilla::UniquePtr<TMimeType<char_type>> Parse(
const nsTSubstring<char_type>& aStr);
static RefPtr<TMimeType<char_type>> Parse(
const nsTSubstring<char_type>& aMimeType);
// @param aMimeType - the mimetype string
// @param aOutEssence - will hold the value of the content-type
@ -84,6 +85,8 @@ class TMimeType final {
// @param aValue - the value of the parameter
void SetParameterValue(const nsTSubstring<char_type>& aName,
const nsTSubstring<char_type>& aValue);
NS_INLINE_DECL_REFCOUNTING(TMimeType)
};
using MimeType = TMimeType<char16_t>;

Просмотреть файл

@ -9,12 +9,10 @@
#include "MimeType.h"
#include "nsString.h"
using mozilla::UniquePtr;
TEST(MimeType, EmptyString)
{
const auto in = u""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Empty string";
}
@ -22,7 +20,7 @@ TEST(MimeType, EmptyString)
TEST(MimeType, JustWhitespace)
{
const auto in = u" \t\r\n "_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Just whitespace";
}
@ -30,7 +28,7 @@ TEST(MimeType, JustWhitespace)
TEST(MimeType, JustBackslash)
{
const auto in = u"\\"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Just backslash";
}
@ -38,7 +36,7 @@ TEST(MimeType, JustBackslash)
TEST(MimeType, JustForwardslash)
{
const auto in = u"/"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Just forward slash";
}
@ -46,7 +44,7 @@ TEST(MimeType, JustForwardslash)
TEST(MimeType, MissingType1)
{
const auto in = u"/bogus"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing type #1";
}
@ -54,7 +52,7 @@ TEST(MimeType, MissingType1)
TEST(MimeType, MissingType2)
{
const auto in = u" \r\n\t/bogus"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing type #2";
}
@ -62,7 +60,7 @@ TEST(MimeType, MissingType2)
TEST(MimeType, MissingSubtype1)
{
const auto in = u"bogus"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing subtype #1";
}
@ -70,7 +68,7 @@ TEST(MimeType, MissingSubtype1)
TEST(MimeType, MissingSubType2)
{
const auto in = u"bogus/"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing subtype #2";
}
@ -78,7 +76,7 @@ TEST(MimeType, MissingSubType2)
TEST(MimeType, MissingSubType3)
{
const auto in = u"bogus;"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing subtype #3";
}
@ -86,7 +84,7 @@ TEST(MimeType, MissingSubType3)
TEST(MimeType, MissingSubType4)
{
const auto in = u"bogus; \r\n\t"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Missing subtype #3";
}
@ -94,7 +92,7 @@ TEST(MimeType, MissingSubType4)
TEST(MimeType, ExtraForwardSlash)
{
const auto in = u"bogus/bogus/;"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Extra forward slash";
}
@ -102,7 +100,7 @@ TEST(MimeType, ExtraForwardSlash)
TEST(MimeType, WhitespaceInType)
{
const auto in = u"t\re\nx\tt /html"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Type with whitespace";
}
@ -110,7 +108,7 @@ TEST(MimeType, WhitespaceInType)
TEST(MimeType, WhitespaceInSubtype)
{
const auto in = u"text/ h\rt\nm\tl"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Subtype with whitespace";
}
@ -118,7 +116,7 @@ TEST(MimeType, WhitespaceInSubtype)
TEST(MimeType, NonAlphanumericMediaType1)
{
const auto in = u"</>"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #1";
}
@ -126,7 +124,7 @@ TEST(MimeType, NonAlphanumericMediaType1)
TEST(MimeType, NonAlphanumericMediaType2)
{
const auto in = u"(/)"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #2";
}
@ -134,7 +132,7 @@ TEST(MimeType, NonAlphanumericMediaType2)
TEST(MimeType, NonAlphanumericMediaType3)
{
const auto in = u"{/}"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #3";
}
@ -142,7 +140,7 @@ TEST(MimeType, NonAlphanumericMediaType3)
TEST(MimeType, NonAlphanumericMediaType4)
{
const auto in = u"\"/\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #4";
}
@ -150,7 +148,7 @@ TEST(MimeType, NonAlphanumericMediaType4)
TEST(MimeType, NonAlphanumericMediaType5)
{
const auto in = u"\0/\0"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #5";
}
@ -158,7 +156,7 @@ TEST(MimeType, NonAlphanumericMediaType5)
TEST(MimeType, NonAlphanumericMediaType6)
{
const auto in = u"text/html(;doesnot=matter"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-alphanumeric media type #6";
}
@ -166,7 +164,7 @@ TEST(MimeType, NonAlphanumericMediaType6)
TEST(MimeType, NonLatin1MediaType1)
{
const auto in = u"ÿ/ÿ"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-latin1 media type #1";
}
@ -174,7 +172,7 @@ TEST(MimeType, NonLatin1MediaType1)
TEST(MimeType, NonLatin1MediaType2)
{
const auto in = u"\x0100/\x0100"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_FALSE(parsed)
<< "Non-latin1 media type #2";
}
@ -182,7 +180,7 @@ TEST(MimeType, NonLatin1MediaType2)
TEST(MimeType, MultipleParameters)
{
const auto in = u"text/html;charset=gbk;no=1;charset_=gbk_;yes=2"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsString out;
@ -194,7 +192,7 @@ TEST(MimeType, MultipleParameters)
TEST(MimeType, DuplicateParameter1)
{
const auto in = u"text/html;charset=gbk;charset=windows-1255"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsString out;
@ -206,7 +204,7 @@ TEST(MimeType, DuplicateParameter1)
TEST(MimeType, DuplicateParameter2)
{
const auto in = u"text/html;charset=();charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsString out;
@ -218,7 +216,7 @@ TEST(MimeType, DuplicateParameter2)
TEST(MimeType, CString)
{
const auto in = "text/html;charset=();charset=GBK"_ns;
UniquePtr<CMimeType> parsed = CMimeType::Parse(in);
RefPtr<CMimeType> parsed = CMimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsCString out;
@ -234,7 +232,7 @@ TEST(MimeType, CString)
TEST(MimeType, NonAlphanumericParametersAreQuoted)
{
const auto in = u"text/html;test=\x00FF\\;charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsString out;
@ -249,7 +247,7 @@ TEST(MimeType, NonAlphanumericParametersAreQuoted)
TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace1)
{
const auto in = u"text/html;charset= g\\\"bk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -261,7 +259,7 @@ TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace1)
TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace2)
{
const auto in = u"text/html;charset= \"g\\bk\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -273,7 +271,7 @@ TEST(MimeType, ParameterQuotedIfHasLeadingWhitespace2)
TEST(MimeType, ParameterQuotedIfHasInternalWhitespace)
{
const auto in = u"text/html;charset=g \\b\"k"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -285,7 +283,7 @@ TEST(MimeType, ParameterQuotedIfHasInternalWhitespace)
TEST(MimeType, ImproperlyQuotedParameter1)
{
const auto in = u"x/x;test=\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -297,7 +295,7 @@ TEST(MimeType, ImproperlyQuotedParameter1)
TEST(MimeType, ImproperlyQuotedParameter2)
{
const auto in = u"x/x;test=\"\\"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -309,7 +307,7 @@ TEST(MimeType, ImproperlyQuotedParameter2)
TEST(MimeType, NonLatin1ParameterIgnored)
{
const auto in = u"x/x;test=\xFFFD;x=x"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -321,7 +319,7 @@ TEST(MimeType, NonLatin1ParameterIgnored)
TEST(MimeType, ParameterIgnoredIfWhitespaceInName1)
{
const auto in = u"text/html;charset =gbk;charset=123"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -333,7 +331,7 @@ TEST(MimeType, ParameterIgnoredIfWhitespaceInName1)
TEST(MimeType, ParameterIgnoredIfWhitespaceInName2)
{
const auto in = u"text/html;cha rset =gbk;charset=123"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -345,7 +343,7 @@ TEST(MimeType, ParameterIgnoredIfWhitespaceInName2)
TEST(MimeType, WhitespaceTrimmed)
{
const auto in = u"\n\r\t text/plain\n\r\t ;\n\r\t charset=123\n\r\t "_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -357,7 +355,7 @@ TEST(MimeType, WhitespaceTrimmed)
TEST(MimeType, WhitespaceOnlyParameterIgnored)
{
const auto in = u"x/x;x= \r\n\t"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -369,7 +367,7 @@ TEST(MimeType, WhitespaceOnlyParameterIgnored)
TEST(MimeType, IncompleteParameterIgnored1)
{
const auto in = u"x/x;test"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -381,7 +379,7 @@ TEST(MimeType, IncompleteParameterIgnored1)
TEST(MimeType, IncompleteParameterIgnored2)
{
const auto in = u"x/x;test="_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -393,7 +391,7 @@ TEST(MimeType, IncompleteParameterIgnored2)
TEST(MimeType, IncompleteParameterIgnored3)
{
const auto in = u"x/x;test= \r\n\t"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -405,7 +403,7 @@ TEST(MimeType, IncompleteParameterIgnored3)
TEST(MimeType, IncompleteParameterIgnored4)
{
const auto in = u"text/html;test;charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -417,7 +415,7 @@ TEST(MimeType, IncompleteParameterIgnored4)
TEST(MimeType, IncompleteParameterIgnored5)
{
const auto in = u"text/html;test=;charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -429,7 +427,7 @@ TEST(MimeType, IncompleteParameterIgnored5)
TEST(MimeType, EmptyParameterIgnored1)
{
const auto in = u"text/html ; ; charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -441,7 +439,7 @@ TEST(MimeType, EmptyParameterIgnored1)
TEST(MimeType, EmptyParameterIgnored2)
{
const auto in = u"text/html;;;;charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -453,7 +451,7 @@ TEST(MimeType, EmptyParameterIgnored2)
TEST(MimeType, InvalidParameterIgnored1)
{
const auto in = u"text/html;';charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -465,7 +463,7 @@ TEST(MimeType, InvalidParameterIgnored1)
TEST(MimeType, InvalidParameterIgnored2)
{
const auto in = u"text/html;\";charset=gbk;=123; =321"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -477,7 +475,7 @@ TEST(MimeType, InvalidParameterIgnored2)
TEST(MimeType, InvalidParameterIgnored3)
{
const auto in = u"text/html;charset= \"\u007F;charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -490,7 +488,7 @@ TEST(MimeType, InvalidParameterIgnored4)
{
const auto in = nsLiteralString(
u"text/html;charset=\"\u007F;charset=foo\";charset=GBK;charset=");
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -502,7 +500,7 @@ TEST(MimeType, InvalidParameterIgnored4)
TEST(MimeType, SingleQuotes1)
{
const auto in = u"text/html;charset='gbk'"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -514,7 +512,7 @@ TEST(MimeType, SingleQuotes1)
TEST(MimeType, SingleQuotes2)
{
const auto in = u"text/html;charset='gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -526,7 +524,7 @@ TEST(MimeType, SingleQuotes2)
TEST(MimeType, SingleQuotes3)
{
const auto in = u"text/html;charset=gbk'"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -538,7 +536,7 @@ TEST(MimeType, SingleQuotes3)
TEST(MimeType, SingleQuotes4)
{
const auto in = u"text/html;charset=';charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -550,7 +548,7 @@ TEST(MimeType, SingleQuotes4)
TEST(MimeType, SingleQuotes5)
{
const auto in = u"text/html;charset=''';charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -562,7 +560,7 @@ TEST(MimeType, SingleQuotes5)
TEST(MimeType, DoubleQuotes1)
{
const auto in = u"text/html;charset=\"gbk\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -574,7 +572,7 @@ TEST(MimeType, DoubleQuotes1)
TEST(MimeType, DoubleQuotes2)
{
const auto in = u"text/html;charset=\"gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -586,7 +584,7 @@ TEST(MimeType, DoubleQuotes2)
TEST(MimeType, DoubleQuotes3)
{
const auto in = u"text/html;charset=gbk\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -598,7 +596,7 @@ TEST(MimeType, DoubleQuotes3)
TEST(MimeType, DoubleQuotes4)
{
const auto in = u"text/html;charset=\" gbk\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -610,7 +608,7 @@ TEST(MimeType, DoubleQuotes4)
TEST(MimeType, DoubleQuotes5)
{
const auto in = u"text/html;charset=\"gbk \""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -622,7 +620,7 @@ TEST(MimeType, DoubleQuotes5)
TEST(MimeType, DoubleQuotes6)
{
const auto in = u"text/html;charset=\"\\ gbk\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -634,7 +632,7 @@ TEST(MimeType, DoubleQuotes6)
TEST(MimeType, DoubleQuotes7)
{
const auto in = u"text/html;charset=\"\\g\\b\\k\""_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -646,7 +644,7 @@ TEST(MimeType, DoubleQuotes7)
TEST(MimeType, DoubleQuotes8)
{
const auto in = u"text/html;charset=\"gbk\"x"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -658,7 +656,7 @@ TEST(MimeType, DoubleQuotes8)
TEST(MimeType, DoubleQuotes9)
{
const auto in = u"text/html;charset=\"\";charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -670,7 +668,7 @@ TEST(MimeType, DoubleQuotes9)
TEST(MimeType, DoubleQuotes10)
{
const auto in = u"text/html;charset=\";charset=GBK"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -682,7 +680,7 @@ TEST(MimeType, DoubleQuotes10)
TEST(MimeType, UnexpectedCodePoints)
{
const auto in = u"text/html;charset={gbk}"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -699,7 +697,7 @@ TEST(MimeType, LongTypesSubtypesAccepted)
"2345678901234567890123456789012345678901234567890123456789/"
"012345678901234567890123456789012345678901234567890123456789012345678901"
"2345678901234567890123456789012345678901234567890123456789");
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -716,7 +714,7 @@ TEST(MimeType, LongParametersAccepted)
"012345678901234567890123456789012345678901234567890123456789012345678901"
"2345678901234567890123456789012345678901234567890123456789=x;charset="
"gbk");
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -744,7 +742,7 @@ TEST(MimeType, AllValidCharactersAccepted1)
u"\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED"
u"\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8"
u"\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF\"");
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -756,7 +754,7 @@ TEST(MimeType, AllValidCharactersAccepted1)
TEST(MimeType, CaseNormalization1)
{
const auto in = u"TEXT/PLAIN;CHARSET=TEST"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -775,7 +773,7 @@ TEST(MimeType, CaseNormalization2)
".^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$"
"%&'*+-.^_`|~"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -794,7 +792,7 @@ TEST(MimeType, CaseNormalization2)
TEST(MimeType, LegacyCommentSyntax1)
{
const auto in = u"text/html;charset=gbk("_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;
@ -806,7 +804,7 @@ TEST(MimeType, LegacyCommentSyntax1)
TEST(MimeType, LegacyCommentSyntax2)
{
const auto in = u"text/html;x=(;charset=gbk"_ns;
UniquePtr<MimeType> parsed = MimeType::Parse(in);
RefPtr<MimeType> parsed = MimeType::Parse(in);
ASSERT_TRUE(parsed)
<< "Parsing succeeded";
nsAutoString out;

Просмотреть файл

@ -1039,7 +1039,7 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
bool foundOpaqueRedirect = false;
nsAutoCString contentType;
nsAutoCString contentType(VoidCString());
int64_t contentLength = InternalResponse::UNKNOWN_BODY_SIZE;
rv = channel->GetContentLength(&contentLength);
@ -1119,13 +1119,13 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
MOZ_ASSERT(!result.Failed());
}
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
if (uri && uri->SchemeIs("data")) {
nsDataChannel* dchan = static_cast<nsDataChannel*>(channel.get());
MOZ_ASSERT(dchan);
contentType.Assign(dchan->MimeType());
} else {
if (baseChan) {
RefPtr<CMimeType> fullMimeType(baseChan->FullMimeType());
if (fullMimeType) {
fullMimeType->Serialize(contentType);
}
}
if (contentType.IsVoid()) {
channel->GetContentType(contentType);
if (!contentType.IsEmpty()) {
nsAutoCString contentCharset;

Просмотреть файл

@ -1208,13 +1208,13 @@ bool XMLHttpRequestMainThread::IsSafeHeader(
bool XMLHttpRequestMainThread::GetContentType(nsACString& aValue) const {
MOZ_ASSERT(mChannel);
nsCOMPtr<nsIURI> uri;
if (NS_SUCCEEDED(mChannel->GetURI(getter_AddRefs(uri))) &&
uri->SchemeIs("data")) {
nsDataChannel* dchan = static_cast<nsDataChannel*>(mChannel.get());
MOZ_ASSERT(dchan);
aValue.Assign(dchan->MimeType());
return true;
nsCOMPtr<nsIBaseChannel> baseChan = do_QueryInterface(mChannel);
if (baseChan) {
RefPtr<CMimeType> fullMimeType(baseChan->FullMimeType());
if (fullMimeType) {
fullMimeType->Serialize(aValue);
return true;
}
}
if (NS_SUCCEEDED(mChannel->GetContentType(aValue))) {
nsCString value;
@ -3141,7 +3141,7 @@ void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
if (uploadContentType.IsVoid()) {
uploadContentType = defaultContentType;
} else if (aBodyIsDocumentOrString) {
UniquePtr<CMimeType> contentTypeRecord =
RefPtr<CMimeType> contentTypeRecord =
CMimeType::Parse(uploadContentType);
nsAutoCString charset;
if (contentTypeRecord &&
@ -3404,7 +3404,7 @@ void XMLHttpRequestMainThread::OverrideMimeType(const nsAString& aMimeType,
return;
}
UniquePtr<MimeType> parsed = MimeType::Parse(aMimeType);
RefPtr<MimeType> parsed = MimeType::Parse(aMimeType);
if (parsed) {
parsed->Serialize(mOverrideMimeType);
} else {

Просмотреть файл

@ -980,3 +980,15 @@ NS_IMETHODIMP nsBaseChannel::SetContentRange(
mContentRange = aRange;
return NS_OK;
}
NS_IMETHODIMP nsBaseChannel::GetFullMimeType(RefPtr<TMimeType<char>>* aOut) {
if (aOut) {
*aOut = mFullMimeType;
}
return NS_OK;
}
NS_IMETHODIMP nsBaseChannel::SetFullMimeType(RefPtr<TMimeType<char>> aType) {
mFullMimeType = aType;
return NS_OK;
}

Просмотреть файл

@ -6,6 +6,7 @@
#ifndef nsBaseChannel_h__
#define nsBaseChannel_h__
#include "mozilla/dom/MimeType.h"
#include "mozilla/Maybe.h"
#include "mozilla/MozPromise.h"
#include "mozilla/UniquePtr.h"
@ -292,6 +293,7 @@ class nsBaseChannel
bool mOpenRedirectChannel{false};
uint32_t mRedirectFlags{0};
RefPtr<mozilla::net::ContentRange> mContentRange;
RefPtr<CMimeType> mFullMimeType;
protected:
nsCString mContentType;

Просмотреть файл

@ -5,6 +5,7 @@
#include "nsISupports.idl"
%{C++
#include "mozilla/dom/MimeType.h"
#include "mozilla/net/ContentRange.h"
%}
@ -17,6 +18,7 @@
*/
native ContentRangeRef(RefPtr<mozilla::net::ContentRange>);
native MimeTypeRef(RefPtr<TMimeType<char>>);
[uuid(036d5cd7-9a53-40e3-9c72-c2ffaa15aa2b)]
interface nsIBaseChannel : nsISupports {
@ -27,6 +29,13 @@ interface nsIBaseChannel : nsISupports {
*/
attribute ContentRangeRef contentRange;
/**
* Used by fetch and XMLHttpRequest to get the standards-compliant value they
* should set for the Content-Type header on response (if nullptr, they will
* use Firefox-specific values from nsIChannel::GetContentType and GetCharset).
*/
attribute MimeTypeRef fullMimeType;
%{C++
RefPtr<mozilla::net::ContentRange> ContentRange() {
RefPtr<mozilla::net::ContentRange> range;
@ -43,6 +52,12 @@ interface nsIBaseChannel : nsISupports {
SetContentRange(range);
return true;
}
RefPtr<CMimeType> FullMimeType() {
RefPtr<CMimeType> type;
mozilla::Unused << GetFullMimeType(&type);
return type;
}
%}
};

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsDataChannel.h"
#include "mozilla/Base64.h"
#include "mozilla/dom/MimeType.h"
#include "nsDataHandler.h"
#include "nsIInputStream.h"
#include "nsEscape.h"
@ -59,9 +60,10 @@ nsresult nsDataChannel::OpenContentStream(bool async, nsIInputStream** result,
nsCString contentType, contentCharset;
nsDependentCSubstring dataRange;
RefPtr<CMimeType> fullMimeType;
bool lBase64;
rv = nsDataHandler::ParsePathWithoutRef(path, contentType, &contentCharset,
lBase64, &dataRange, &mMimeType);
lBase64, &dataRange, &fullMimeType);
if (NS_FAILED(rv)) return rv;
// This will avoid a copy if nothing needs to be unescaped.
@ -103,6 +105,7 @@ nsresult nsDataChannel::OpenContentStream(bool async, nsIInputStream** result,
SetContentType(contentType);
SetContentCharset(contentCharset);
SetFullMimeType(std::move(fullMimeType));
mContentLength = contentLen;
// notify "data-channel-opened" observers

Просмотреть файл

@ -16,14 +16,10 @@ class nsDataChannel : public nsBaseChannel {
public:
explicit nsDataChannel(nsIURI* uri) { SetURI(uri); }
const nsACString& MimeType() const { return mMimeType; }
protected:
[[nodiscard]] virtual nsresult OpenContentStream(
bool async, nsIInputStream** result, nsIChannel** channel) override;
nsCString mMimeType;
private:
nsresult MaybeSendDataChannelOpenNotification();
};

Просмотреть файл

@ -161,7 +161,7 @@ nsresult nsDataHandler::ParsePathWithoutRef(const nsACString& aPath,
nsCString* aContentCharset,
bool& aIsBase64,
nsDependentCSubstring* aDataBuffer,
nsCString* aMimeType) {
RefPtr<CMimeType>* aMimeType) {
static constexpr auto kCharset = "charset"_ns;
// This implements https://fetch.spec.whatwg.org/#data-url-processor
@ -200,18 +200,18 @@ nsresult nsDataHandler::ParsePathWithoutRef(const nsACString& aPath,
// This also checks for instances of ;base64 in the middle of the MimeType.
// This is against the current spec, but we're doing it because we have
// historically seen webcompat issues relying on this (see bug 781693).
if (mozilla::UniquePtr<CMimeType> parsed = CMimeType::Parse(mimeType)) {
if (RefPtr<CMimeType> parsed = CMimeType::Parse(mimeType)) {
parsed->GetEssence(aContentType);
if (aContentCharset) {
parsed->GetParameterValue(kCharset, *aContentCharset);
}
if (aMimeType) {
parsed->Serialize(*aMimeType);
}
if (parsed->IsBase64() &&
!StaticPrefs::network_url_strict_data_url_base64_placement()) {
aIsBase64 = true;
}
if (aMimeType) {
*aMimeType = std::move(parsed);
}
} else {
// "If mimeTypeRecord is failure, then set mimeTypeRecord to
// text/plain;charset=US-ASCII."
@ -220,7 +220,8 @@ nsresult nsDataHandler::ParsePathWithoutRef(const nsACString& aPath,
aContentCharset->AssignLiteral("US-ASCII");
}
if (aMimeType) {
aMimeType->AssignLiteral("text/plain;charset=US-ASCII");
*aMimeType = new CMimeType("text"_ns, "plain"_ns);
(*aMimeType)->SetParameterValue("charset"_ns, "US-ASCII"_ns);
}
}

Просмотреть файл

@ -6,6 +6,7 @@
#ifndef nsDataHandler_h___
#define nsDataHandler_h___
#include "mozilla/dom/MimeType.h"
#include "nsIProtocolHandler.h"
#include "nsWeakReference.h"
@ -50,7 +51,7 @@ class nsDataHandler : public nsIProtocolHandler,
[[nodiscard]] static nsresult ParsePathWithoutRef(
const nsACString& aPath, nsCString& aContentType,
nsCString* aContentCharset, bool& aIsBase64,
nsDependentCSubstring* aDataBuffer, nsCString* aMimeType = nullptr);
nsDependentCSubstring* aDataBuffer, RefPtr<CMimeType>* = nullptr);
};
#endif /* nsDataHandler_h___ */