Commit 6e0f5220 authored by Rob Buis's avatar Rob Buis Committed by Commit Bot

Be strict on request's Content-Type

Be strict on request's Content-Type by only allowing whitespace
before type and after subtype.

Behavior matches Firefox.

Bug: 902681
Change-Id: Id08c0c56076c5b4aa6e335893f663b7d91229da1
Reviewed-on: https://chromium-review.googlesource.com/c/1341508
Commit-Queue: Rob Buis <rbuis@igalia.com>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609667}
parent 8b5e1ba8
...@@ -449,10 +449,12 @@ bool MimeUtil::ParseMimeTypeWithoutParameter( ...@@ -449,10 +449,12 @@ bool MimeUtil::ParseMimeTypeWithoutParameter(
std::string* top_level_type, std::string* top_level_type,
std::string* subtype) const { std::string* subtype) const {
std::vector<std::string> components = base::SplitString( std::vector<std::string> components = base::SplitString(
type_string, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); type_string, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
if (components.size() != 2 || if (components.size() != 2)
!HttpUtil::IsToken(components[0]) || return false;
!HttpUtil::IsToken(components[1])) TrimWhitespaceASCII(components[0], base::TRIM_LEADING, &components[0]);
TrimWhitespaceASCII(components[1], base::TRIM_TRAILING, &components[1]);
if (!HttpUtil::IsToken(components[0]) || !HttpUtil::IsToken(components[1]))
return false; return false;
if (top_level_type) if (top_level_type)
......
...@@ -66,6 +66,9 @@ NET_EXPORT bool MatchesMimeType(const std::string& mime_type_pattern, ...@@ -66,6 +66,9 @@ NET_EXPORT bool MatchesMimeType(const std::string& mime_type_pattern,
// //
// If |top_level_type| is non-NULL, sets it to parsed top-level type string. // If |top_level_type| is non-NULL, sets it to parsed top-level type string.
// If |subtype| is non-NULL, sets it to parsed subtype string. // If |subtype| is non-NULL, sets it to parsed subtype string.
//
// This function strips leading and trailing whitespace from the MIME type.
// TODO: investigate if we should strip strictly HTTP whitespace.
NET_EXPORT bool ParseMimeTypeWithoutParameter(const std::string& type_string, NET_EXPORT bool ParseMimeTypeWithoutParameter(const std::string& type_string,
std::string* top_level_type, std::string* top_level_type,
std::string* subtype); std::string* subtype);
......
...@@ -231,6 +231,32 @@ TEST(MimeUtilTest, TestParseMimeTypeWithoutParameter) { ...@@ -231,6 +231,32 @@ TEST(MimeUtilTest, TestParseMimeTypeWithoutParameter) {
EXPECT_FALSE(ParseMimeTypeWithoutParameter("application/a/b/c", NULL, NULL)); EXPECT_FALSE(ParseMimeTypeWithoutParameter("application/a/b/c", NULL, NULL));
// Test leading and trailing whitespace
EXPECT_TRUE(ParseMimeTypeWithoutParameter(" text/plain", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain ", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text /plain", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/ plain ", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ttext/plain", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\t", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\t/plain", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\tplain ", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("\vtext/plain", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\v", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\v/plain", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\vplain ", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("\rtext/plain", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\r", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\r/plain", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\rplain ", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ntext/plain", NULL, NULL));
EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\n", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\n/plain", NULL, NULL));
EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\nplain ", NULL, NULL));
//EXPECT_TRUE(ParseMimeTypeWithoutParameter("video/mime;parameter")); //EXPECT_TRUE(ParseMimeTypeWithoutParameter("video/mime;parameter"));
} }
......
This is a testharness.js-based test.
FAIL Preflight for {"content-type":"text /plain"} assert_unreached: Should have rejected: undefined Reached unreachable code
FAIL Preflight for {"content-type":"text\t/\tplain"} assert_unreached: Should have rejected: undefined Reached unreachable code
PASS No preflight for {"content-type":"text/plain;"}
PASS No preflight for {"content-type":"text/plain;garbage"}
PASS Preflight for {"content-type":"text/plain;garbage\u0001\u0002"}
PASS Preflight for {"content-type":"text/plain,"}
PASS Preflight for {"content-type":",text/plain"}
PASS Preflight for {"content-type":"text/plain,text/plain"}
PASS Preflight for {"content-type":"text/plain,x/x"}
PASS Preflight for {"content-type":"text/plain\u000b"}
PASS Preflight for {"content-type":"text/plain\f"}
PASS Preflight for {"content-type":"application/www-form-urlencoded"}
PASS Preflight for {"content-type":"application/x-www-form-urlencoded;"}
PASS No preflight for {"content-type":"multipart/form-data"}
PASS Preflight for {"content-type":"multipart/form-data;\""}
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Preflight for {"content-type":"text /plain"} assert_unreached: Should have rejected: undefined Reached unreachable code
FAIL Preflight for {"content-type":"text\t/\tplain"} assert_unreached: Should have rejected: undefined Reached unreachable code
PASS No preflight for {"content-type":"text/plain;"}
PASS No preflight for {"content-type":"text/plain;garbage"}
PASS Preflight for {"content-type":"text/plain;garbage\u0001\u0002"}
PASS Preflight for {"content-type":"text/plain,"}
PASS Preflight for {"content-type":",text/plain"}
PASS Preflight for {"content-type":"text/plain,text/plain"}
PASS Preflight for {"content-type":"text/plain,x/x"}
PASS Preflight for {"content-type":"text/plain\u000b"}
PASS Preflight for {"content-type":"text/plain\f"}
PASS Preflight for {"content-type":"application/www-form-urlencoded"}
PASS Preflight for {"content-type":"application/x-www-form-urlencoded;"}
PASS No preflight for {"content-type":"multipart/form-data"}
PASS Preflight for {"content-type":"multipart/form-data;\""}
Harness: the test ran to completion.
This is a testharness.js-based test. This is a testharness.js-based test.
Found 71 tests; 44 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Setup. PASS Setup.
PASS "data://test/,X" PASS "data://test/,X"
FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
...@@ -31,7 +31,7 @@ PASS "data:%1F,%FF" ...@@ -31,7 +31,7 @@ PASS "data:%1F,%FF"
PASS "data:\0,%FF" PASS "data:\0,%FF"
PASS "data:%00,%FF" PASS "data:%00,%FF"
PASS "data:text/html ,X" PASS "data:text/html ,X"
FAIL "data:text / html,X" assert_equals: expected "text/plain;charset=US-ASCII" but got "text / html" PASS "data:text / html,X"
PASS "data:†,X" PASS "data:†,X"
PASS "data:†/†,X" PASS "data:†/†,X"
PASS "data:X,X" PASS "data:X,X"
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 71 tests; 44 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Setup. PASS Setup.
PASS "data://test/,X" PASS "data://test/,X"
FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
...@@ -31,7 +31,7 @@ PASS "data:%1F,%FF" ...@@ -31,7 +31,7 @@ PASS "data:%1F,%FF"
PASS "data:\0,%FF" PASS "data:\0,%FF"
PASS "data:%00,%FF" PASS "data:%00,%FF"
PASS "data:text/html ,X" PASS "data:text/html ,X"
FAIL "data:text / html,X" assert_equals: expected "text/plain;charset=US-ASCII" but got "text / html" PASS "data:text / html,X"
PASS "data:†,X" PASS "data:†,X"
PASS "data:†/†,X" PASS "data:†/†,X"
PASS "data:X,X" PASS "data:X,X"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment