WebKit Bugzilla
Attachment 357702 Details for
Bug 180526
: Update MIME type parser
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-180526-20181219204444.patch (text/plain), 42.46 KB, created by
Rob Buis
on 2018-12-19 11:44:46 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rob Buis
Created:
2018-12-19 11:44:46 PST
Size:
42.46 KB
patch
obsolete
>Subversion Revision: 239377 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index e6746ddceac50203acf3a2f5daa4ab8011e7b175..f8d939439d7c210205fc3a85f09d8ff2b713a22c 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,44 @@ >+2018-12-19 Rob Buis <rbuis@igalia.com> >+ >+ Update MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=180526 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add an enum to allow two modes of MIME type parsing, one mode >+ to keep supporting RFC2045 as before, and one mode to support >+ the updated MIME parser from mimesniff [1]. Mimesniff support >+ brings the following changes: >+ - allows parameter names without matching =value. >+ - skips whitespace after subtype, parameter value and before >+ parameter name. >+ - lower cases MIME type and parameter name. >+ - parameter names parsed before are discarded. >+ >+ [1] https://mimesniff.spec.whatwg.org/ >+ >+ Test: web-platform-tests/xhr/overridemimetype-blob.html >+ >+ * platform/network/ParsedContentType.cpp: >+ (WebCore::DummyParsedContentType::setContentType const): >+ (WebCore::DummyParsedContentType::setContentTypeParameter const): >+ (WebCore::isQuotedStringTokenCharacter): >+ (WebCore::isTokenCharacter): >+ (WebCore::parseToken): >+ (WebCore::containsNonTokenCharacters): >+ (WebCore::parseQuotedString): >+ (WebCore::parseContentType): >+ (WebCore::isValidContentType): >+ (WebCore::ParsedContentType::ParsedContentType): >+ (WebCore::ParsedContentType::setContentType): >+ (WebCore::isNonTokenCharacter): >+ (WebCore::isNonQuotedStringTokenCharacter): >+ (WebCore::ParsedContentType::setContentTypeParameter): >+ * platform/network/ParsedContentType.h: >+ * xml/XMLHttpRequest.cpp: >+ (WebCore::XMLHttpRequest::send): >+ (WebCore::XMLHttpRequest::overrideMimeType): >+ > 2018-12-19 Alicia Boya GarcÃa <aboya@igalia.com> > > [MSE] Remove unused method: stopAskingForMoreSamples() >diff --git a/Source/WebCore/platform/network/ParsedContentType.cpp b/Source/WebCore/platform/network/ParsedContentType.cpp >index d729a05dbc0a528172a48ea9371cd8c51f3e1002..a31f28b4165707694c413ed8bab261bd22c6ee28 100644 >--- a/Source/WebCore/platform/network/ParsedContentType.cpp >+++ b/Source/WebCore/platform/network/ParsedContentType.cpp >@@ -38,8 +38,8 @@ namespace WebCore { > > class DummyParsedContentType { > public: >- void setContentType(const SubstringRange&) const { } >- void setContentTypeParameter(const SubstringRange&, const SubstringRange&) const { } >+ void setContentType(const SubstringRange&, Mode) const { } >+ void setContentTypeParameter(const String&, const String&, Mode) const { } > }; > > static void skipSpaces(const String& input, unsigned& startIndex) >@@ -48,12 +48,19 @@ static void skipSpaces(const String& input, unsigned& startIndex) > ++startIndex; > } > >-static bool isTokenCharacter(char c) >+static bool isQuotedStringTokenCharacter(UChar c) >+{ >+ return (c >= ' ' && c <= '~') || (c >= 0x80 && c <= 0xFF) || c == '\t'; >+} >+ >+static bool isTokenCharacter(UChar c) > { > return isASCII(c) && c > ' ' && c != '"' && c != '(' && c != ')' && c != ',' && c != '/' && (c < ':' || c > '@') && (c < '[' || c > ']'); > } > >-static std::optional<SubstringRange> parseToken(const String& input, unsigned& startIndex) >+using CharacterMeetsCondition = bool (*)(UChar); >+ >+static std::optional<SubstringRange> parseToken(const String& input, unsigned& startIndex, CharacterMeetsCondition characterMeetsCondition, Mode mode, bool skipTrailingWhitespace = false) > { > unsigned inputLength = input.length(); > unsigned tokenStart = startIndex; >@@ -62,18 +69,31 @@ static std::optional<SubstringRange> parseToken(const String& input, unsigned& s > if (tokenEnd >= inputLength) > return std::nullopt; > >- while (tokenEnd < inputLength) { >- if (!isTokenCharacter(input[tokenEnd])) >+ while (tokenEnd < inputLength && characterMeetsCondition(input[tokenEnd])) { >+ if (mode == Mode::Rfc2045 && !isTokenCharacter(input[tokenEnd])) > break; > ++tokenEnd; > } > > if (tokenEnd == tokenStart) > return std::nullopt; >+ if (skipTrailingWhitespace) { >+ while (input[tokenEnd - 1] == ' ') >+ --tokenEnd; >+ } > return SubstringRange(tokenStart, tokenEnd - tokenStart); > } > >-static std::optional<SubstringRange> parseQuotedString(const String& input, unsigned& startIndex) >+static bool containsNonTokenCharacters(const String& input, SubstringRange range) >+{ >+ for (unsigned index = 0;index < range.second;++index) { >+ if (!isTokenCharacter(input[range.first + index])) >+ return true; >+ } >+ return false; >+} >+ >+static std::optional<SubstringRange> parseQuotedString(const String& input, unsigned& startIndex, Mode mode) > { > unsigned inputLength = input.length(); > unsigned quotedStringStart = startIndex + 1; >@@ -88,8 +108,11 @@ static std::optional<SubstringRange> parseQuotedString(const String& input, unsi > bool lastCharacterWasBackslash = false; > char currentCharacter; > while ((currentCharacter = input[quotedStringEnd++]) != '"' || lastCharacterWasBackslash) { >- if (quotedStringEnd >= inputLength) >- return std::nullopt; >+ if (quotedStringEnd >= inputLength) { >+ if (mode == Mode::Rfc2045) >+ return std::nullopt; >+ break; >+ } > if (currentCharacter == '\\' && !lastCharacterWasBackslash) { > lastCharacterWasBackslash = true; > continue; >@@ -152,7 +175,7 @@ static String substringForRange(const String& string, const SubstringRange& rang > // ; to use within parameter values > > template <class ReceiverType> >-bool parseContentType(const String& contentType, ReceiverType& receiver) >+bool parseContentType(const String& contentType, ReceiverType& receiver, Mode mode) > { > unsigned index = 0; > unsigned contentTypeLength = contentType.length(); >@@ -163,8 +186,10 @@ bool parseContentType(const String& contentType, ReceiverType& receiver) > } > > unsigned contentTypeStart = index; >- auto typeRange = parseToken(contentType, index); >- if (!typeRange) { >+ auto typeRange = parseToken(contentType, index, [] (UChar ch) { >+ return ch != '/'; >+ }, mode); >+ if (!typeRange || containsNonTokenCharacters(contentType, *typeRange)) { > LOG_ERROR("Invalid Content-Type, invalid type value."); > return false; > } >@@ -174,8 +199,10 @@ bool parseContentType(const String& contentType, ReceiverType& receiver) > return false; > } > >- auto subTypeRange = parseToken(contentType, index); >- if (!subTypeRange) { >+ auto subTypeRange = parseToken(contentType, index, [] (UChar ch) { >+ return ch != ';'; >+ }, mode, mode == Mode::MimeSniff); >+ if (!subTypeRange || containsNonTokenCharacters(contentType, *subTypeRange)) { > LOG_ERROR("Invalid Content-Type, invalid subtype value."); > return false; > } >@@ -183,46 +210,69 @@ bool parseContentType(const String& contentType, ReceiverType& receiver) > // There should not be any quoted strings until we reach the parameters. > size_t semiColonIndex = contentType.find(';', contentTypeStart); > if (semiColonIndex == notFound) { >- receiver.setContentType(SubstringRange(contentTypeStart, contentTypeLength - contentTypeStart)); >+ receiver.setContentType(SubstringRange(contentTypeStart, contentTypeLength - contentTypeStart), mode); > return true; > } > >- receiver.setContentType(SubstringRange(contentTypeStart, semiColonIndex - contentTypeStart)); >+ receiver.setContentType(SubstringRange(contentTypeStart, semiColonIndex - contentTypeStart), mode); > index = semiColonIndex + 1; > while (true) { > skipSpaces(contentType, index); >- auto keyRange = parseToken(contentType, index); >- if (!keyRange || index >= contentTypeLength) { >+ auto keyRange = parseToken(contentType, index, [] (UChar ch) { >+ return ch != ';' && ch != '='; >+ }, mode); >+ if (mode == Mode::Rfc2045 && (!keyRange || index >= contentTypeLength)) { > LOG_ERROR("Invalid Content-Type parameter name."); > return false; > } > > // Should we tolerate spaces here? >- if (contentType[index++] != '=' || index >= contentTypeLength) { >- LOG_ERROR("Invalid Content-Type malformed parameter."); >- return false; >+ if (mode == Mode::Rfc2045) { >+ if (contentType[index++] != '=' || index >= contentTypeLength) { >+ LOG_ERROR("Invalid Content-Type malformed parameter."); >+ return false; >+ } >+ } else { >+ if (index >= contentTypeLength) >+ break; >+ if (contentType[index] != '=' && contentType[index] != ';') { >+ LOG_ERROR("Invalid Content-Type malformed parameter."); >+ return false; >+ } >+ if (contentType[index++] == ';') >+ continue; > } > >+ String parameterName = substringForRange(contentType, *keyRange); >+ > // Should we tolerate spaces here? >- String value; > std::optional<SubstringRange> valueRange; >- if (contentType[index] == '"') >- valueRange = parseQuotedString(contentType, index); >- else >- valueRange = parseToken(contentType, index); >+ if (contentType[index] == '"') { >+ valueRange = parseQuotedString(contentType, index, mode); >+ if (mode == Mode::MimeSniff) { >+ parseToken(contentType, index, [] (UChar ch) { >+ return ch != ';'; >+ }, mode); >+ } >+ } else { >+ valueRange = parseToken(contentType, index, [] (UChar ch) { >+ return ch != ';'; >+ }, mode, mode == Mode::MimeSniff); >+ } > > if (!valueRange) { > LOG_ERROR("Invalid Content-Type, invalid parameter value."); > return false; > } > >- // Should we tolerate spaces here? >- if (index < contentTypeLength && contentType[index++] != ';') { >+ String parameterValue = substringForRange(contentType, *valueRange); >+ >+ if (mode == Mode::Rfc2045 && index < contentTypeLength && contentType[index++] != ';') { > LOG_ERROR("Invalid Content-Type, invalid character at the end of key/value parameter."); > return false; > } > >- receiver.setContentTypeParameter(*keyRange, *valueRange); >+ receiver.setContentTypeParameter(parameterName, parameterValue, mode); > > if (index >= contentTypeLength) > return true; >@@ -231,19 +281,19 @@ bool parseContentType(const String& contentType, ReceiverType& receiver) > return true; > } > >-bool isValidContentType(const String& contentType) >+bool isValidContentType(const String& contentType, Mode mode) > { > if (contentType.contains('\r') || contentType.contains('\n')) > return false; > > DummyParsedContentType parsedContentType = DummyParsedContentType(); >- return parseContentType<DummyParsedContentType>(contentType, parsedContentType); >+ return parseContentType<DummyParsedContentType>(contentType, parsedContentType, mode); > } > >-ParsedContentType::ParsedContentType(const String& contentType) >+ParsedContentType::ParsedContentType(const String& contentType, Mode mode) > : m_contentType(contentType.stripWhiteSpace()) > { >- parseContentType<ParsedContentType>(m_contentType, *this); >+ parseContentType<ParsedContentType>(m_contentType, *this, mode); > } > > String ParsedContentType::charset() const >@@ -261,14 +311,31 @@ size_t ParsedContentType::parameterCount() const > return m_parameters.size(); > } > >-void ParsedContentType::setContentType(const SubstringRange& contentRange) >+void ParsedContentType::setContentType(const SubstringRange& contentRange, Mode mode) > { > m_mimeType = substringForRange(m_contentType, contentRange).stripWhiteSpace(); >+ if (mode == Mode::MimeSniff) >+ m_mimeType.convertToASCIILowercase(); >+} >+ >+static bool isNonTokenCharacter(UChar ch) >+{ >+ return !isTokenCharacter(ch); >+} >+ >+static bool isNonQuotedStringTokenCharacter(UChar ch) >+{ >+ return !isQuotedStringTokenCharacter(ch); > } > >-void ParsedContentType::setContentTypeParameter(const SubstringRange& key, const SubstringRange& value) >+void ParsedContentType::setContentTypeParameter(const String& keyName, const String& keyValue, Mode mode) > { >- m_parameters.set(substringForRange(m_contentType, key), substringForRange(m_contentType, value)); >+ if (mode == Mode::MimeSniff) { >+ if (m_parameters.contains(keyName) || keyName.find(isNonTokenCharacter) != notFound || keyValue.find(isNonQuotedStringTokenCharacter) != notFound) >+ return; >+ keyName.convertToASCIILowercase(); >+ } >+ m_parameters.set(keyName, keyValue); > } > > } >diff --git a/Source/WebCore/platform/network/ParsedContentType.h b/Source/WebCore/platform/network/ParsedContentType.h >index 6363b3e4d63587890a3cc8c11c56890abd19d0ee..85f9f9d3bc5adf97e1a148b83bc52b57e7e06fc7 100644 >--- a/Source/WebCore/platform/network/ParsedContentType.h >+++ b/Source/WebCore/platform/network/ParsedContentType.h >@@ -36,14 +36,18 @@ > > namespace WebCore { > >+enum class Mode { >+ Rfc2045, >+ MimeSniff >+}; > // <index, length> > typedef std::pair<unsigned, unsigned> SubstringRange; >-bool isValidContentType(const String&); >+WEBCORE_EXPORT bool isValidContentType(const String&, Mode = Mode::Rfc2045); > > // FIXME: add support for comments. > class ParsedContentType { > public: >- explicit ParsedContentType(const String&); >+ explicit ParsedContentType(const String&, Mode = Mode::Rfc2045); > > String mimeType() const { return m_mimeType; } > String charset() const; >@@ -54,9 +58,9 @@ public: > > private: > template<class ReceiverType> >- friend bool parseContentType(const String&, ReceiverType&); >- void setContentType(const SubstringRange&); >- void setContentTypeParameter(const SubstringRange&, const SubstringRange&); >+ friend bool parseContentType(const String&, ReceiverType&, Mode); >+ void setContentType(const SubstringRange&, Mode); >+ void setContentTypeParameter(const String&, const String&, Mode); > > typedef HashMap<String, String> KeyValuePairs; > String m_contentType; >diff --git a/Source/WebCore/xml/XMLHttpRequest.cpp b/Source/WebCore/xml/XMLHttpRequest.cpp >index b9eccf352fa940749e671dfef6e6f8e7b0905a18..8d8255076a6bac1c2556037f3460989b1664cdb9 100644 >--- a/Source/WebCore/xml/XMLHttpRequest.cpp >+++ b/Source/WebCore/xml/XMLHttpRequest.cpp >@@ -525,7 +525,7 @@ ExceptionOr<void> XMLHttpRequest::send(Blob& body) > if (m_method != "GET" && m_method != "HEAD" && m_url.protocolIsInHTTPFamily()) { > if (!m_requestHeaders.contains(HTTPHeaderName::ContentType)) { > const String& blobType = body.type(); >- if (!blobType.isEmpty() && isValidContentType(blobType)) >+ if (!blobType.isEmpty() && isValidContentType(blobType, Mode::MimeSniff)) > m_requestHeaders.set(HTTPHeaderName::ContentType, blobType); > else { > // From FileAPI spec, whenever media type cannot be determined, empty string must be returned. >@@ -785,7 +785,7 @@ ExceptionOr<void> XMLHttpRequest::overrideMimeType(const String& mimeType) > return Exception { InvalidStateError }; > > m_mimeTypeOverride = "application/octet-stream"_s; >- if (isValidContentType(mimeType)) >+ if (isValidContentType(mimeType, Mode::MimeSniff)) > m_mimeTypeOverride = mimeType; > > return { }; >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 1b01b1da638e62107d84808ddd839e688b9d4569..986b32ab740998f617063f38a355d847d4e0dd31 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,16 @@ >+2018-12-19 Rob Buis <rbuis@igalia.com> >+ >+ Update MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=180526 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add unit tests for both parse modes of ParsedContentType. >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp: Added. >+ (TestWebKitAPI::TEST): >+ > 2018-12-18 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] A copied text selection is pasted as a web archive attachment in the entry view in Messages >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 7e8ed3be51484308e0d8a1a9b78ba358eff554a5..322c7f0716bc27f3ad2078b4d44c3d74d18a6b1a 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -685,6 +685,7 @@ > A5A729F11F622AA700DE5A28 /* WKNavigationResponse.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5A729F01F622A9A00DE5A28 /* WKNavigationResponse.mm */; }; > A5B149DE1F5A19EA00C6DAFF /* MIMETypeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5B149DD1F5A19DC00C6DAFF /* MIMETypeRegistry.cpp */; }; > A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */; }; >+ AA96CAB621C7DB5000FD2F97 /* ParsedContentType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA96CAB421C7DB4200FD2F97 /* ParsedContentType.cpp */; }; > AD57AC201DA7465000FF1BDE /* DidRemoveFrameFromHiearchyInPageCache_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD57AC1E1DA7464D00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache_Bundle.cpp */; }; > AD57AC211DA7465B00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD57AC1F1DA7464D00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache.cpp */; }; > AD57AC221DA7466E00FF1BDE /* many-iframes.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = AD57AC1D1DA7463800FF1BDE /* many-iframes.html */; }; >@@ -1895,6 +1896,7 @@ > A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WindowlessWebViewWithMedia.html; sourceTree = "<group>"; }; > A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowlessWebViewWithMedia.mm; sourceTree = "<group>"; }; > A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CheckedArithmeticOperations.cpp; sourceTree = "<group>"; }; >+ AA96CAB421C7DB4200FD2F97 /* ParsedContentType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentType.cpp; sourceTree = "<group>"; }; > ABF510632A19B8AC7EC40E17 /* AbortableTaskQueue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AbortableTaskQueue.cpp; sourceTree = "<group>"; }; > AD57AC1D1DA7463800FF1BDE /* many-iframes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "many-iframes.html"; sourceTree = "<group>"; }; > AD57AC1E1DA7464D00FF1BDE /* DidRemoveFrameFromHiearchyInPageCache_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DidRemoveFrameFromHiearchyInPageCache_Bundle.cpp; sourceTree = "<group>"; }; >@@ -2650,6 +2652,7 @@ > CE1866471F72E8F100A0CAB6 /* MarkedText.cpp */, > A5B149DD1F5A19DC00C6DAFF /* MIMETypeRegistry.cpp */, > CD225C071C45A69200140761 /* ParsedContentRange.cpp */, >+ AA96CAB421C7DB4200FD2F97 /* ParsedContentType.cpp */, > 041A1E33216FFDBC00789E0A /* PublicSuffix.cpp */, > F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */, > CDCFA7A91E45122F00C2433D /* SampleMap.cpp */, >@@ -4070,6 +4073,7 @@ > 7CCE7EC71A411A7E00447C4C /* PageVisibilityStateWithWindowChanges.mm in Sources */, > 7CCE7F091A411AE600447C4C /* ParentFrame.cpp in Sources */, > 7C83E0511D0A641800FEBCF3 /* ParsedContentRange.cpp in Sources */, >+ AA96CAB621C7DB5000FD2F97 /* ParsedContentType.cpp in Sources */, > F44C79FF20F9E8710014478C /* ParserYieldTokenTests.mm in Sources */, > 7CCE7F0A1A411AE600447C4C /* PasteboardNotifications.mm in Sources */, > 9BCB7C2820130600003E7C0C /* PasteHTML.mm in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..ce84af4df790bc96303897c48a0c34bb76848585 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp >@@ -0,0 +1,99 @@ >+/* >+ * Copyright (C) 2018 Igalia, S.L. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+ >+#include "Test.h" >+#include <WebCore/ParsedContentType.h> >+ >+using namespace WebCore; >+ >+namespace TestWebKitAPI { >+ >+TEST(ParsedContentType, MimeSniff) >+{ >+ EXPECT_TRUE(isValidContentType("text/plain", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType(" text/plain", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType(" text/plain ", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text /plain", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text/ plain", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text / plain", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("te xt/plain", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text/pla in", Mode::MimeSniff)); >+ >+ EXPECT_FALSE(isValidContentType("text", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text/", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("/plain", Mode::MimeSniff)); >+ >+ EXPECT_TRUE(isValidContentType("text/plain;", Mode::MimeSniff)); >+ >+ EXPECT_TRUE(isValidContentType("text/plain;test", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain; test", Mode::MimeSniff)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=value", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain; test=value", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test =value", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test= value", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=value ", Mode::MimeSniff)); >+ >+ EXPECT_TRUE(isValidContentType("text/plain;test=\"value\"", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=\"value", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=\"value\"foo", Mode::MimeSniff)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=\"value\"foo;foo=bar", Mode::MimeSniff)); >+} >+ >+TEST(ParsedContentType, Rfc2045) >+{ >+ EXPECT_TRUE(isValidContentType("text/plain", Mode::Rfc2045)); >+ EXPECT_TRUE(isValidContentType(" text/plain", Mode::Rfc2045)); >+ EXPECT_TRUE(isValidContentType(" text/plain ", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text /plain", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/ plain", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text / plain", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("te xt/plain", Mode::Rfc2045)); >+ EXPECT_TRUE(isValidContentType("text/pla in", Mode::Rfc2045)); >+ >+ EXPECT_FALSE(isValidContentType("text", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("/plain", Mode::Rfc2045)); >+ >+ EXPECT_FALSE(isValidContentType("text/plain;", Mode::Rfc2045)); >+ >+ EXPECT_FALSE(isValidContentType("text/plain;test", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain; test", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=", Mode::Rfc2045)); >+ EXPECT_TRUE(isValidContentType("text/plain;test=value", Mode::Rfc2045)); >+ EXPECT_TRUE(isValidContentType("text/plain; test=value", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test =value", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test= value", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=value ", Mode::Rfc2045)); >+ >+ EXPECT_TRUE(isValidContentType("text/plain;test=\"value\"", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=\"value", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=\"value\"foo", Mode::Rfc2045)); >+ EXPECT_FALSE(isValidContentType("text/plain;test=\"value\"foo;foo=bar", Mode::Rfc2045)); >+} >+ >+} // namespace TestWebKitAPI >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 821c75729f3285ce23ea580cf366877608b2de67..22e9c4ac286f3fee7efe5cb546159bb826e7aed5 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2018-12-19 Rob Buis <rbuis@igalia.com> >+ >+ Update MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=180526 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Adjust test expectation. >+ >+ * http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt: >+ * http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt: >+ * http/tests/xmlhttprequest/post-blob-content-type-tests.js: >+ > 2018-12-18 Justin Michaud <justin_michaud@apple.com> > > Update CSS Properties and Values API to use new cycle fallback behaviour >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 2fb9a323f574bd81c97dd915f5f4da4263719a20..86236940d0e7229cb9195886d303b8b27fccebb4 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,14 @@ >+2018-12-19 Rob Buis <rbuis@igalia.com> >+ >+ Update MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=180526 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update improved test expectations. >+ >+ * web-platform-tests/xhr/overridemimetype-blob-expected.txt: >+ > 2018-12-18 Justin Michaud <justin_michaud@apple.com> > > Update CSS Properties and Values API to use new cycle fallback behaviour >diff --git a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt >index 8809c112547c57d5a720f242a83bd11f2a380b1b..5103f1951f2d80d293af7240ba24c63f80b16d2d 100644 >--- a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt >+++ b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-async-expected.txt >@@ -12,7 +12,7 @@ PASS expectedMimeType is "" > PASS expectedMimeType is "" > PASS expectedMimeType is "" > PASS expectedMimeType is "" >-PASS expectedMimeType is "" >+PASS expectedMimeType is "multipart/mixed;boundary=\"--blob-boundary" > PASS expectedMimeType is "multipart/mixed;boundary=\"--blob-boundary\"" > PASS expectedMimeType is "" > PASS expectedMimeType is "" >diff --git a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt >index b0aeed99ba64a12beabf84b7097b324b0ca27e26..213936d40b651d3537957af2e60bf0f79ab027fa 100644 >--- a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt >+++ b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-sync-expected.txt >@@ -12,7 +12,7 @@ PASS expectedMimeType is "" > PASS expectedMimeType is "" > PASS expectedMimeType is "" > PASS expectedMimeType is "" >-PASS expectedMimeType is "" >+PASS expectedMimeType is "multipart/mixed;boundary=\"--blob-boundary" > PASS expectedMimeType is "multipart/mixed;boundary=\"--blob-boundary\"" > PASS expectedMimeType is "" > PASS expectedMimeType is "" >diff --git a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-tests.js b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-tests.js >index 49852f236ec86ac4b90235af7d840ab740927b32..ce5f35b0678ccdda888d8b7e247a404e117b3ef1 100644 >--- a/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-tests.js >+++ b/LayoutTests/http/tests/xmlhttprequest/post-blob-content-type-tests.js >@@ -23,7 +23,7 @@ var xhrBlobTestCases = [{ > expectedMime: '' > }, { > mime: 'multipart/mixed;boundary="--blob-boundary', >- expectedMime: '' >+ expectedMime: 'multipart/mixed;boundary="--blob-boundary' > }, { > mime: 'multipart/mixed;boundary="--blob-boundary"', > expectedMime: 'multipart/mixed;boundary="--blob-boundary"' >diff --git a/LayoutTests/imported/w3c/web-platform-tests/xhr/overridemimetype-blob-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/xhr/overridemimetype-blob-expected.txt >index 02561ca2e3f97639025137c90de8837a1b1d306b..7de610dd51064cb2680f05e3e27fba7bba9045b4 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/xhr/overridemimetype-blob-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/xhr/overridemimetype-blob-expected.txt >@@ -4,59 +4,59 @@ PASS Use text/xml as fallback MIME type, 2 > PASS Loading data⦠> FAIL 1) MIME types need to be parsed and serialized: text/html;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" > FAIL 2) MIME types need to be parsed and serialized: TEXT/HTML;CHARSET=GBK assert_equals: expected "text/html;charset=GBK" but got "text/html" >-FAIL 3) MIME types need to be parsed and serialized: text/html;charset=gbk( assert_equals: expected "text/html;charset=\"gbk(\"" but got "application/octet-stream" >-FAIL 4) MIME types need to be parsed and serialized: text/html;x=(;charset=gbk assert_equals: expected "text/html;x=\"(\";charset=gbk" but got "application/octet-stream" >+FAIL 3) MIME types need to be parsed and serialized: text/html;charset=gbk( assert_equals: expected "text/html;charset=\"gbk(\"" but got "text/html" >+FAIL 4) MIME types need to be parsed and serialized: text/html;x=(;charset=gbk assert_equals: expected "text/html;x=\"(\";charset=gbk" but got "text/html" > FAIL 5) MIME types need to be parsed and serialized: text/html;charset=gbk;charset=windows-1255 assert_equals: expected "text/html;charset=gbk" but got "text/html" >-FAIL 6) MIME types need to be parsed and serialized: text/html;charset=();charset=GBK assert_equals: expected "text/html;charset=\"()\"" but got "application/octet-stream" >-FAIL 7) MIME types need to be parsed and serialized: text/html;charset =gbk assert_equals: expected "text/html" but got "application/octet-stream" >+FAIL 6) MIME types need to be parsed and serialized: text/html;charset=();charset=GBK assert_equals: expected "text/html;charset=\"()\"" but got "text/html" >+PASS 7) MIME types need to be parsed and serialized: text/html;charset =gbk > FAIL 8) MIME types need to be parsed and serialized: text/html ;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" > FAIL 9) MIME types need to be parsed and serialized: text/html; charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >-FAIL 10) MIME types need to be parsed and serialized: text/html;charset= gbk assert_equals: expected "text/html;charset=\" gbk\"" but got "application/octet-stream" >-FAIL 11) MIME types need to be parsed and serialized: text/html;charset= "gbk" assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "application/octet-stream" >+FAIL 10) MIME types need to be parsed and serialized: text/html;charset= gbk assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html" >+FAIL 11) MIME types need to be parsed and serialized: text/html;charset= "gbk" assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html" > FAIL 12) MIME types need to be parsed and serialized: text/html;charset='gbk' assert_equals: expected "text/html;charset='gbk'" but got "text/html" > FAIL 13) MIME types need to be parsed and serialized: text/html;charset='gbk assert_equals: expected "text/html;charset='gbk" but got "text/html" > FAIL 14) MIME types need to be parsed and serialized: text/html;charset=gbk' assert_equals: expected "text/html;charset=gbk'" but got "text/html" > FAIL 15) MIME types need to be parsed and serialized: text/html;charset=';charset=GBK assert_equals: expected "text/html;charset='" but got "text/html" >-FAIL 16) MIME types need to be parsed and serialized: text/html;test;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >+FAIL 16) MIME types need to be parsed and serialized: text/html;test;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" > FAIL 17) MIME types need to be parsed and serialized: text/html;test=;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 18) MIME types need to be parsed and serialized: text/html;';charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 19) MIME types need to be parsed and serialized: text/html;";charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 20) MIME types need to be parsed and serialized: text/html ; ; charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 21) MIME types need to be parsed and serialized: text/html;;;;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 22) MIME types need to be parsed and serialized: text/html;charset= ";charset=GBK assert_equals: expected "text/html;charset=GBK" but got "application/octet-stream" >+FAIL 18) MIME types need to be parsed and serialized: text/html;';charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >+FAIL 19) MIME types need to be parsed and serialized: text/html;";charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >+FAIL 20) MIME types need to be parsed and serialized: text/html ; ; charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >+FAIL 21) MIME types need to be parsed and serialized: text/html;;;;charset=gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >+FAIL 22) MIME types need to be parsed and serialized: text/html;charset= ";charset=GBK assert_equals: expected "text/html;charset=GBK" but got "text/html" > FAIL 23) MIME types need to be parsed and serialized: text/html;charset=";charset=foo";charset=GBK assert_equals: expected "text/html;charset=GBK" but got "text/html" > FAIL 24) MIME types need to be parsed and serialized: text/html;charset="gbk" assert_equals: expected "text/html;charset=gbk" but got "text/html" >-FAIL 25) MIME types need to be parsed and serialized: text/html;charset="gbk assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >-FAIL 26) MIME types need to be parsed and serialized: text/html;charset=gbk" assert_equals: expected "text/html;charset=\"gbk\\\"\"" but got "application/octet-stream" >+FAIL 25) MIME types need to be parsed and serialized: text/html;charset="gbk assert_equals: expected "text/html;charset=gbk" but got "text/html" >+FAIL 26) MIME types need to be parsed and serialized: text/html;charset=gbk" assert_equals: expected "text/html;charset=\"gbk\\\"\"" but got "text/html" > FAIL 27) MIME types need to be parsed and serialized: text/html;charset=" gbk" assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html" > FAIL 28) MIME types need to be parsed and serialized: text/html;charset="gbk " assert_equals: expected "text/html;charset=\"gbk \"" but got "text/html" > FAIL 29) MIME types need to be parsed and serialized: text/html;charset="\ gbk" assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html" > FAIL 30) MIME types need to be parsed and serialized: text/html;charset="\g\b\k" assert_equals: expected "text/html;charset=gbk" but got "text/html" >-FAIL 31) MIME types need to be parsed and serialized: text/html;charset="gbk"x assert_equals: expected "text/html;charset=gbk" but got "application/octet-stream" >+FAIL 31) MIME types need to be parsed and serialized: text/html;charset="gbk"x assert_equals: expected "text/html;charset=gbk" but got "text/html" > FAIL 32) MIME types need to be parsed and serialized: text/html;charset="";charset=GBK assert_equals: expected "text/html;charset=\"\"" but got "text/html" >-FAIL 33) MIME types need to be parsed and serialized: text/html;charset=";charset=GBK assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "application/octet-stream" >+FAIL 33) MIME types need to be parsed and serialized: text/html;charset=";charset=GBK assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "text/html" > FAIL 34) MIME types need to be parsed and serialized: text/html;charset={gbk} assert_equals: expected "text/html;charset=\"{gbk}\"" but got "text/html" > FAIL 35) MIME types need to be parsed and serialized: text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk assert_equals: expected "text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk" but got "text/html" > PASS 36) MIME types need to be parsed and serialized: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 > FAIL 37) MIME types need to be parsed and serialized: !#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz assert_equals: expected "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz;!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz=!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" but got "!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz/!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" > FAIL 38) MIME types need to be parsed and serialized: x/x;x=" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Â ¡¢£¤¥¦§¨©ª«¬Â®¯°±²³´µ¶·¸¹º»¼½¾¿ÃÃÃÃÃà ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃà áâãäåæçèéêëìÃîïðñòóôõö÷øùúûüýþÿ" assert_equals: expected "x/x;x=\"\t !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Â ¡¢£¤¥¦§¨©ª«¬Â®¯°±²³´µ¶·¸¹º»¼½¾¿ÃÃÃÃÃà ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃà áâãäåæçèéêëìÃîïðñòóôõö÷øùúûüýþÿ\"" but got "x/x" >-FAIL 39) MIME types need to be parsed and serialized: x/x;test assert_equals: expected "x/x" but got "application/octet-stream" >-FAIL 40) MIME types need to be parsed and serialized: x/x;test="\ assert_equals: expected "x/x;test=\"\\\\"" but got "application/octet-stream" >-FAIL 41) MIME types need to be parsed and serialized: x/x;x= assert_equals: expected "x/x" but got "application/octet-stream" >-FAIL 42) MIME types need to be parsed and serialized: x/x;x= assert_equals: expected "x/x" but got "application/octet-stream" >-FAIL 43) MIME types need to be parsed and serialized: text/html;test=ÿ;charset=gbk assert_equals: expected "text/html;test=\"ÿ\";charset=gbk" but got "application/octet-stream" >-FAIL 44) MIME types need to be parsed and serialized: x/x;test=�;x=x assert_equals: expected "x/x;x=x" but got "application/octet-stream" >+PASS 39) MIME types need to be parsed and serialized: x/x;test >+FAIL 40) MIME types need to be parsed and serialized: x/x;test="\ assert_equals: expected "x/x;test=\"\\\\"" but got "x/x" >+PASS 41) MIME types need to be parsed and serialized: x/x;x= >+PASS 42) MIME types need to be parsed and serialized: x/x;x= >+FAIL 43) MIME types need to be parsed and serialized: text/html;test=ÿ;charset=gbk assert_equals: expected "text/html;test=\"ÿ\";charset=gbk" but got "text/html" >+FAIL 44) MIME types need to be parsed and serialized: x/x;test=�;x=x assert_equals: expected "x/x;x=x" but got "x/x" > PASS 45) MIME types need to be parsed and serialized: > PASS 46) MIME types need to be parsed and serialized: > PASS 47) MIME types need to be parsed and serialized: / > PASS 48) MIME types need to be parsed and serialized: bogus > PASS 49) MIME types need to be parsed and serialized: bogus/ >-PASS 50) MIME types need to be parsed and serialized: bogus/ >+FAIL 50) MIME types need to be parsed and serialized: bogus/ assert_equals: expected "application/octet-stream" but got "bogus/" > PASS 51) MIME types need to be parsed and serialized: bogus/bogus/; > PASS 52) MIME types need to be parsed and serialized: </> > PASS 53) MIME types need to be parsed and serialized: (/) > PASS 54) MIME types need to be parsed and serialized: ÿ/ÿ >-FAIL 55) MIME types need to be parsed and serialized: text/html(;doesnot=matter assert_equals: expected "application/octet-stream" but got "text/html(" >+PASS 55) MIME types need to be parsed and serialized: text/html(;doesnot=matter > FAIL 56) MIME types need to be parsed and serialized: {/} assert_equals: expected "application/octet-stream" but got "{/}" > PASS 57) MIME types need to be parsed and serialized: Ä/Ä >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 180526
:
348014
|
356923
|
356928
|
357400
|
357401
|
357403
|
357443
|
357469
|
357682
|
357684
|
357687
|
357690
|
357691
|
357702
|
358515
|
358898
|
358906
|
358907
|
358917
|
359860
|
360118
|
360123
|
360129
|
360134
|
360136
|
360144
|
360303
|
360343
|
360350
|
360355
|
362245
|
362316
|
362323
|
362342
|
362348
|
362360
|
362378
|
362384
|
362387
|
362390
|
362397
|
362416
|
362418
|
362430
|
362437
|
362483
|
362486
|
362497
|
362506
|
362526
|
390349