WebKit Bugzilla
Attachment 361627 Details for
Bug 193909
: Implement serializing in MIME type parser
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-193909-20190210142310.patch (text/plain), 15.56 KB, created by
Rob Buis
on 2019-02-10 05:23:11 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rob Buis
Created:
2019-02-10 05:23:11 PST
Size:
15.56 KB
patch
obsolete
>Subversion Revision: 241247 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 50320c2098d5ae6c2b825ce142d640a5d73fa98c..169d98af2bfe0e5670257cd2bc95de020fbede5a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,29 @@ >+2019-02-10 Rob Buis <rbuis@igalia.com> >+ >+ Implement serializing in MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=193909 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Implement serializing in MIME type parser [1], to preserve the parameter >+ order the Vector m_parameterNames is introduced, since HashMaps do not >+ guarantee any order. >+ >+ Test: ParsedContentType.Serialize >+ >+ [1] https://mimesniff.spec.whatwg.org/#serializing-a-mime-type >+ >+ * platform/network/ParsedContentType.cpp: >+ (WebCore::skipSpaces): >+ (WebCore::parseQuotedString): >+ (WebCore::ParsedContentType::parseContentType): >+ (WebCore::ParsedContentType::parameterValueForName const): >+ (WebCore::ParsedContentType::parameterCount const): >+ (WebCore::ParsedContentType::setContentType): >+ (WebCore::ParsedContentType::setContentTypeParameter): >+ (WebCore::ParsedContentType::serialize const): >+ * platform/network/ParsedContentType.h: >+ > 2019-02-09 Darin Adler <darin@apple.com> > > Eliminate unnecessary String temporaries by using StringConcatenateNumbers >diff --git a/Source/WebCore/platform/network/ParsedContentType.cpp b/Source/WebCore/platform/network/ParsedContentType.cpp >index ceb54a72700c3ccc076dd687b2fb1bec74e7d84a..ef1c5cd0e78e83eb46750fff044f72760bae1ea2 100644 >--- a/Source/WebCore/platform/network/ParsedContentType.cpp >+++ b/Source/WebCore/platform/network/ParsedContentType.cpp >@@ -32,13 +32,15 @@ > #include "config.h" > #include "ParsedContentType.h" > >+#include "HTTPParsers.h" > #include <wtf/text/CString.h> >+#include <wtf/text/StringBuilder.h> > > namespace WebCore { > > static void skipSpaces(const String& input, unsigned& startIndex) > { >- while (startIndex < input.length() && input[startIndex] == ' ') >+ while (startIndex < input.length() && isHTTPSpace(input[startIndex])) > ++startIndex; > } > >@@ -96,8 +98,11 @@ static Optional<SubstringRange> parseQuotedString(const String& input, unsigned& > if (quotedStringEnd >= inputLength) > return WTF::nullopt; > >- if (input[quotedStringEnd++] != '"' || quotedStringEnd >= inputLength) >- return WTF::nullopt; >+ if (input[quotedStringEnd++] != '"' || quotedStringEnd >= inputLength) { >+ if (mode == Mode::Rfc2045) >+ return WTF::nullopt; >+ return SubstringRange(quotedStringStart, quotedStringEnd - quotedStringStart); >+ } > > bool lastCharacterWasBackslash = false; > char currentCharacter; >@@ -114,7 +119,9 @@ static Optional<SubstringRange> parseQuotedString(const String& input, unsigned& > if (lastCharacterWasBackslash) > lastCharacterWasBackslash = false; > } >- return SubstringRange(quotedStringStart, quotedStringEnd - quotedStringStart - 1); >+ if (input[quotedStringEnd - 1] == '"') >+ return SubstringRange(quotedStringStart, quotedStringEnd - quotedStringStart - 1); >+ return SubstringRange(quotedStringStart, quotedStringEnd - quotedStringStart); > } > > static String substringForRange(const String& string, const SubstringRange& range) >@@ -190,7 +197,7 @@ static bool containsNewline(UChar ch) > > bool ParsedContentType::parseContentType(Mode mode) > { >- if (m_contentType.find(containsNewline) != notFound) >+ if (mode == Mode::Rfc2045 && m_contentType.find(containsNewline) != notFound) > return false; > unsigned index = 0; > unsigned contentTypeLength = m_contentType.length(); >@@ -311,19 +318,19 @@ String ParsedContentType::charset() const > > String ParsedContentType::parameterValueForName(const String& name) const > { >- return m_parameters.get(name); >+ return m_parameterValues.get(name); > } > > size_t ParsedContentType::parameterCount() const > { >- return m_parameters.size(); >+ return m_parameterValues.size(); > } > > void ParsedContentType::setContentType(const SubstringRange& contentRange, Mode mode) > { > m_mimeType = substringForRange(m_contentType, contentRange).stripWhiteSpace(); > if (mode == Mode::MimeSniff) >- m_mimeType.convertToASCIILowercase(); >+ m_mimeType = m_mimeType.convertToASCIILowercase(); > } > > static bool isNonTokenCharacter(UChar ch) >@@ -338,12 +345,33 @@ static bool isNonQuotedStringTokenCharacter(UChar ch) > > void ParsedContentType::setContentTypeParameter(const String& keyName, const String& keyValue, Mode mode) > { >+ String name = keyName; > if (mode == Mode::MimeSniff) { >- if (m_parameters.contains(keyName) || keyName.find(isNonTokenCharacter) != notFound || keyValue.find(isNonQuotedStringTokenCharacter) != notFound) >+ if (m_parameterValues.contains(keyName) || keyName.find(isNonTokenCharacter) != notFound || keyValue.find(isNonQuotedStringTokenCharacter) != notFound) > return; >- keyName.convertToASCIILowercase(); >+ name = name.convertToASCIILowercase(); >+ } >+ m_parameterValues.set(name, keyValue); >+ m_parameterNames.append(name); >+} >+ >+String ParsedContentType::serialize() const >+{ >+ StringBuilder builder; >+ builder.append(m_mimeType); >+ for (auto& name : m_parameterNames) { >+ builder.append(';'); >+ builder.append(name); >+ builder.append('='); >+ String value = m_parameterValues.get(name); >+ if (value.isEmpty() || value.find(isNonTokenCharacter) != notFound) { >+ builder.append('"'); >+ builder.append(value); >+ builder.append('"'); >+ } else >+ builder.append(value); > } >- m_parameters.set(keyName, keyValue); >+ return builder.toString(); > } > > } >diff --git a/Source/WebCore/platform/network/ParsedContentType.h b/Source/WebCore/platform/network/ParsedContentType.h >index de7df88f7c7fb156e638108a24a5fbe723af1363..49f2e223cd836e558a421ed0f0452b358c2ddc49 100644 >--- a/Source/WebCore/platform/network/ParsedContentType.h >+++ b/Source/WebCore/platform/network/ParsedContentType.h >@@ -47,7 +47,7 @@ WEBCORE_EXPORT bool isValidContentType(const String&, Mode = Mode::MimeSniff); > // FIXME: add support for comments. > class ParsedContentType { > public: >- static Optional<ParsedContentType> create(const String&, Mode = Mode::MimeSniff); >+ WEBCORE_EXPORT static Optional<ParsedContentType> create(const String&, Mode = Mode::MimeSniff); > ParsedContentType(ParsedContentType&&) = default; > > String mimeType() const { return m_mimeType; } >@@ -57,6 +57,8 @@ public: > String parameterValueForName(const String&) const; > size_t parameterCount() const; > >+ WEBCORE_EXPORT String serialize() const; >+ > private: > ParsedContentType(const String&); > ParsedContentType(const ParsedContentType&) = delete; >@@ -67,7 +69,8 @@ private: > > typedef HashMap<String, String> KeyValuePairs; > String m_contentType; >- KeyValuePairs m_parameters; >+ KeyValuePairs m_parameterValues; >+ Vector<String> m_parameterNames; > String m_mimeType; > }; > >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 26456d168ee7df5133a320929e08d7f16adec7dd..a40be6d24e0e530d018af743ae04030415669258 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,17 @@ >+2019-02-10 Rob Buis <rbuis@igalia.com> >+ >+ Implement serializing in MIME type parser >+ https://bugs.webkit.org/show_bug.cgi?id=193909 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add various tests involving upper case, non-ASCII, control/null characters, >+ various HTTP whitespace, single quotes and an unpaired surrogate. >+ >+ * TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp: >+ (TestWebKitAPI::serializeIfValid): >+ (TestWebKitAPI::TEST): >+ > 2019-02-09 Benjamin Poulain <benjamin@webkit.org> > > Add more tests for clampTo<>() >diff --git a/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp >index 155704ad0a233ae4add7334148c5af2007568e4e..3055a3fccd742bda60c28544185c6e1cc03c5544 100644 >--- a/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp >+++ b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentType.cpp >@@ -98,4 +98,113 @@ TEST(ParsedContentType, Rfc2045) > EXPECT_FALSE(isValidContentType("text/plain;test=\"value\"foo;foo=bar", Mode::Rfc2045)); > } > >+static const char* serializeIfValid(const String& input) >+{ >+ if (Optional<ParsedContentType> parsedContentType = ParsedContentType::create(input)) >+ return parsedContentType->serialize().utf8().data(); >+ return "NOTVALID"; >+} >+ >+TEST(ParsedContentType, Serialize) >+{ >+ EXPECT_STREQ(serializeIfValid(""), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid(";"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/\0"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/ "), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/plain"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain\0"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid(" text/plain"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\ttext/plain"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\ntext/plain"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\rtext/plain"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\btext/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/plain "), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain\t"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain\n"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain\r"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain\b"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid(" text/plain "), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\ttext/plain\t"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\ntext/plain\n"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\rtext/plain\r"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("\btext/plain\b"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/PLAIN"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text /plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/ plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text / plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("te xt/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/pla in"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\t/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/\tplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\t/\tplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("te\txt/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/pla\tin"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\n/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/\nplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\n/\nplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("te\nxt/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/pla\nin"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\r/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/\rplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text\r/\rplain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("te\rxt/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/pla\rin"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("/plain"), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("â /â "), "NOTVALID"); >+ EXPECT_STREQ(serializeIfValid("text/\xD8\x88\x12\x34"), "NOTVALID"); >+ >+ EXPECT_STREQ(serializeIfValid("text/plain;"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain; test"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\ttest"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\ntest"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\rtest"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\btest"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test "), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\t"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\n"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\r"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\b"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test="), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=;test=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;TEST=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=VALUE"), "text/plain;test=VALUE"); >+ EXPECT_STREQ(serializeIfValid("text/plain; test=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\ttest=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\ntest=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\rtest=value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\btest=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;\0test=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test =value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\t=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\n=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\r=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test\b=value"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test= value"), "text/plain;test=\" value\""); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\tvalue"), "text/plain;test=\"\tvalue\""); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\nvalue"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\rvalue"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\bvalue"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value "), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value\t"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value\n"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value\r"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value\b"), "text/plain"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"value\""), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"value"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\""), "text/plain;test=\"\""); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"value\"foo"), "text/plain;test=value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"value\"foo;foo=bar"), "text/plain;test=value;foo=bar"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"val\\ue\""), "text/plain;test=\"val\\ue\""); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=\"val\\\"ue\""), "text/plain;test=\"val\\\"ue\""); >+ EXPECT_STREQ(serializeIfValid("text/plain;test='value'"), "text/plain;test='value'"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test='value"), "text/plain;test='value"); >+ EXPECT_STREQ(serializeIfValid("text/plain;test=value'"), "text/plain;test=value'"); >+} >+ > } // namespace TestWebKitAPI
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 193909
:
361430
|
361627
|
361686
|
362241
|
362244