Content-Type parameter values should allow empty quoted strings
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2018 07:35:41 +0000 (07:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2018 07:35:41 +0000 (07:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191388

Patch by Rob Buis <rbuis@igalia.com> on 2018-11-12
Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Include improved expected test result and updated mime-type test:
https://github.com/whatwg/mimesniff/pull/79

* web-platform-tests/mimesniff/mime-types/charset-parameter.window-expected.txt:
* web-platform-tests/mimesniff/mime-types/parsing.any-expected.txt:
* web-platform-tests/mimesniff/mime-types/parsing.any.worker-expected.txt:
* web-platform-tests/mimesniff/mime-types/resources/mime-types.json:
* web-platform-tests/xhr/overridemimetype-blob-expected.txt:

Source/WebCore:

According to RFC 2045 and https://mimesniff.spec.whatwg.org/#parsing-a-mime-type empty
quoted strings are acceptable for Content-Type parameter values. They
are accepted by Firefox and Chrome implementations as well.

Test: web-platform-tests/xhr/overridemimetype-blob.html

* platform/network/ParsedContentType.cpp:
(WebCore::parseToken):
(WebCore::parseQuotedString):
(WebCore::parseContentType):
* platform/network/ParsedContentType.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238124 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/mimesniff/mime-types/charset-parameter.window-expected.txt
LayoutTests/imported/w3c/web-platform-tests/mimesniff/mime-types/parsing.any-expected.txt
LayoutTests/imported/w3c/web-platform-tests/mimesniff/mime-types/parsing.any.worker-expected.txt
LayoutTests/imported/w3c/web-platform-tests/mimesniff/mime-types/resources/mime-types.json
LayoutTests/imported/w3c/web-platform-tests/xhr/overridemimetype-blob-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/platform/network/ParsedContentType.cpp
Source/WebCore/platform/network/ParsedContentType.h

index 64cf282..9b814c4 100644 (file)
@@ -1,3 +1,19 @@
+2018-11-12  Rob Buis  <rbuis@igalia.com>
+
+        Content-Type parameter values should allow empty quoted strings
+        https://bugs.webkit.org/show_bug.cgi?id=191388
+
+        Reviewed by Dean Jackson.
+
+        Include improved expected test result and updated mime-type test:
+        https://github.com/whatwg/mimesniff/pull/79
+
+        * web-platform-tests/mimesniff/mime-types/charset-parameter.window-expected.txt:
+        * web-platform-tests/mimesniff/mime-types/parsing.any-expected.txt:
+        * web-platform-tests/mimesniff/mime-types/parsing.any.worker-expected.txt:
+        * web-platform-tests/mimesniff/mime-types/resources/mime-types.json:
+        * web-platform-tests/xhr/overridemimetype-blob-expected.txt:
+
 2018-11-12  Sihui Liu  <sihui_liu@apple.com>
 
         imported/w3c/web-platform-tests/IndexedDB/keygenerator-explicit.html crashing on iOS device
index 1ad7b93..301ec54 100644 (file)
@@ -31,7 +31,7 @@ FAIL text/html;charset="gbk " assert_equals: expected "GBK" but got "UTF-8"
 FAIL text/html;charset="\ gbk" assert_equals: expected "GBK" but got "UTF-8"
 FAIL text/html;charset="\g\b\k" assert_equals: expected "GBK" but got "UTF-8"
 FAIL text/html;charset="gbk"x assert_equals: expected "GBK" but got "UTF-8"
-FAIL text/html;charset="";charset=GBK assert_equals: expected "GBK" but got "UTF-8"
+PASS text/html;charset="";charset=GBK 
 PASS text/html;charset=";charset=GBK 
 PASS text/html;charset={gbk} 
 PASS text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk 
index 010dc50..f1ea2aa 100644 (file)
@@ -62,8 +62,8 @@ FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/h
 FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html"
 FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x"
 FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html"
-FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk"
-FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "text/html"
+FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"\"" but got "text/html;charset=\"\";charset=gbk"
+FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\"\"" but got "text/html"
 FAIL text/html;charset=";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk"
 FAIL text/html;charset=";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "text/html"
 FAIL text/html;charset={gbk} (Blob/File) assert_equals: Blob expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}"
index fa5928d..fb1107e 100644 (file)
@@ -62,8 +62,8 @@ FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/h
 FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html"
 FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x"
 FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html"
-FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk"
-FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "text/html"
+FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"\"" but got "text/html;charset=\"\";charset=gbk"
+FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\"\"" but got "text/html"
 FAIL text/html;charset=";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk"
 FAIL text/html;charset=";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "text/html"
 FAIL text/html;charset={gbk} (Blob/File) assert_equals: Blob expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}"
index 1d0b152..8918b35 100644 (file)
   },
   {
     "input": "text/html;charset=\"\";charset=GBK",
-    "output": "text/html;charset=GBK",
+    "output": "text/html;charset=\"\"",
     "navigable": true,
-    "encoding": "GBK"
+    "encoding": null
   },
   {
     "input": "text/html;charset=\";charset=GBK",
index b684bc7..02561ca 100644 (file)
@@ -33,7 +33,7 @@ FAIL 28) MIME types need to be parsed and serialized: text/html;charset="gbk " a
 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 32) 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 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 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"
index ee2f310..9b405d4 100644 (file)
@@ -1,3 +1,22 @@
+2018-11-12  Rob Buis  <rbuis@igalia.com>
+
+        Content-Type parameter values should allow empty quoted strings
+        https://bugs.webkit.org/show_bug.cgi?id=191388
+
+        Reviewed by Dean Jackson.
+
+        According to RFC 2045 and https://mimesniff.spec.whatwg.org/#parsing-a-mime-type empty
+        quoted strings are acceptable for Content-Type parameter values. They
+        are accepted by Firefox and Chrome implementations as well.
+
+        Test: web-platform-tests/xhr/overridemimetype-blob.html
+
+        * platform/network/ParsedContentType.cpp:
+        (WebCore::parseToken):
+        (WebCore::parseQuotedString):
+        (WebCore::parseContentType):
+        * platform/network/ParsedContentType.h:
+
 2018-11-12  Christopher Reid  <chris.reid@sony.com>
 
         [Curl] Reject entire cookie if the domain fails a tailmatch.
index 8b78297..d729a05 100644 (file)
@@ -53,41 +53,43 @@ static bool isTokenCharacter(char c)
     return isASCII(c) && c > ' ' && c != '"' && c != '(' && c != ')' && c != ',' && c != '/' && (c < ':' || c > '@') && (c < '[' || c > ']');
 }
 
-static SubstringRange parseToken(const String& input, unsigned& startIndex)
+static std::optional<SubstringRange> parseToken(const String& input, unsigned& startIndex)
 {
     unsigned inputLength = input.length();
     unsigned tokenStart = startIndex;
     unsigned& tokenEnd = startIndex;
 
     if (tokenEnd >= inputLength)
-        return SubstringRange();
+        return std::nullopt;
 
     while (tokenEnd < inputLength) {
         if (!isTokenCharacter(input[tokenEnd]))
-            return SubstringRange(tokenStart, tokenEnd - tokenStart);
+            break;
         ++tokenEnd;
     }
 
+    if (tokenEnd == tokenStart)
+        return std::nullopt;
     return SubstringRange(tokenStart, tokenEnd - tokenStart);
 }
 
-static SubstringRange parseQuotedString(const String& input, unsigned& startIndex)
+static std::optional<SubstringRange> parseQuotedString(const String& input, unsigned& startIndex)
 {
     unsigned inputLength = input.length();
     unsigned quotedStringStart = startIndex + 1;
     unsigned& quotedStringEnd = startIndex;
 
     if (quotedStringEnd >= inputLength)
-        return SubstringRange();
+        return std::nullopt;
 
     if (input[quotedStringEnd++] != '"' || quotedStringEnd >= inputLength)
-        return SubstringRange();
+        return std::nullopt;
 
     bool lastCharacterWasBackslash = false;
     char currentCharacter;
     while ((currentCharacter = input[quotedStringEnd++]) != '"' || lastCharacterWasBackslash) {
         if (quotedStringEnd >= inputLength)
-            return SubstringRange();
+            return std::nullopt;
         if (currentCharacter == '\\' && !lastCharacterWasBackslash) {
             lastCharacterWasBackslash = true;
             continue;
@@ -162,7 +164,7 @@ bool parseContentType(const String& contentType, ReceiverType& receiver)
 
     unsigned contentTypeStart = index;
     auto typeRange = parseToken(contentType, index);
-    if (!typeRange.second) {
+    if (!typeRange) {
         LOG_ERROR("Invalid Content-Type, invalid type value.");
         return false;
     }
@@ -173,7 +175,7 @@ bool parseContentType(const String& contentType, ReceiverType& receiver)
     }
 
     auto subTypeRange = parseToken(contentType, index);
-    if (!subTypeRange.second) {
+    if (!subTypeRange) {
         LOG_ERROR("Invalid Content-Type, invalid subtype value.");
         return false;
     }
@@ -189,8 +191,8 @@ bool parseContentType(const String& contentType, ReceiverType& receiver)
     index = semiColonIndex + 1;
     while (true) {
         skipSpaces(contentType, index);
-        SubstringRange keyRange = parseToken(contentType, index);
-        if (!keyRange.second || index >= contentTypeLength) {
+        auto keyRange = parseToken(contentType, index);
+        if (!keyRange || index >= contentTypeLength) {
             LOG_ERROR("Invalid Content-Type parameter name.");
             return false;
         }
@@ -203,13 +205,13 @@ bool parseContentType(const String& contentType, ReceiverType& receiver)
 
         // Should we tolerate spaces here?
         String value;
-        SubstringRange valueRange;
+        std::optional<SubstringRange> valueRange;
         if (contentType[index] == '"')
             valueRange = parseQuotedString(contentType, index);
         else
             valueRange = parseToken(contentType, index);
 
-        if (!valueRange.second) {
+        if (!valueRange) {
             LOG_ERROR("Invalid Content-Type, invalid parameter value.");
             return false;
         }
@@ -220,7 +222,7 @@ bool parseContentType(const String& contentType, ReceiverType& receiver)
             return false;
         }
 
-        receiver.setContentTypeParameter(keyRange, valueRange);
+        receiver.setContentTypeParameter(*keyRange, *valueRange);
 
         if (index >= contentTypeLength)
             return true;
index 684c6c5..6363b3e 100644 (file)
@@ -29,8 +29,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ParsedContentType_h
-#define ParsedContentType_h
+#pragma once
 
 #include <wtf/HashMap.h>
 #include <wtf/text/StringHash.h>
@@ -66,5 +65,3 @@ private:
 };
 
 }
-
-#endif