summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-26 03:50:56 +0000
committergbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-26 03:50:56 +0000
commitad50e8b3bba31d489c91202f6709f80510108b6e (patch)
treed2ff26dd47808b8d3903d25396ccef6731081614
parentd3add5cf33fe302d5fb15f34712dc380e787c5ae (diff)
downloadchromium_src-ad50e8b3bba31d489c91202f6709f80510108b6e.zip
chromium_src-ad50e8b3bba31d489c91202f6709f80510108b6e.tar.gz
chromium_src-ad50e8b3bba31d489c91202f6709f80510108b6e.tar.bz2
Update mime type matching to handle parameters.
R=rvargas@chromium.org BUG=None Review URL: https://chromiumcodereview.appspot.com/11193023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@164256 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/intents/web_intents_util_unittest.cc13
-rw-r--r--net/base/mime_util.cc78
-rw-r--r--net/base/mime_util_unittest.cc41
3 files changed, 116 insertions, 16 deletions
diff --git a/chrome/browser/intents/web_intents_util_unittest.cc b/chrome/browser/intents/web_intents_util_unittest.cc
index 910b809..931204b 100644
--- a/chrome/browser/intents/web_intents_util_unittest.cc
+++ b/chrome/browser/intents/web_intents_util_unittest.cc
@@ -79,4 +79,17 @@ TEST(WebIntentsUtilTest, MimeTypesMatchWildCards) {
EXPECT_FALSE(TypesMatch("**", "image/png"));
}
+TEST(WebIntentsUtilTest, MimeTypesMatchParameters) {
+ EXPECT_TRUE(TypesMatch("*", "video/*;single=true"));
+ EXPECT_TRUE(TypesMatch("*/*", "video/mpg;single=true"));
+ EXPECT_TRUE(TypesMatch("video/*", "video/mpg;single=true"));
+ EXPECT_TRUE(TypesMatch("video/mpg", "video/mpg;single=true"));
+ EXPECT_TRUE(TypesMatch("video/mpg;single=true", "video/mpg;single=true"));
+ EXPECT_TRUE(TypesMatch("video/mpg;a=b;single=true",
+ "video/mpg;single=true;a=b"));
+ EXPECT_FALSE(TypesMatch("video/mpg;a=b;single=true",
+ "video/mpg;single=false;a=b"));
+ EXPECT_FALSE(TypesMatch("video/mpg;single=true", "video/mpg;single=false"));
+}
+
} // namepsace web_intents
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index f851ecd..e8d1813 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+#include <iterator>
#include <map>
#include <string>
@@ -511,41 +513,85 @@ bool MimeUtil::IsSupportedMimeType(const std::string& mime_type) const {
IsSupportedNonImageMimeType(mime_type);
}
+// Tests for MIME parameter equality. Each parameter in the |mime_type_pattern|
+// must be matched by a parameter in the |mime_type|. If there are no
+// parameters in the pattern, the match is a success.
+bool MatchesMimeTypeParameters(const std::string& mime_type_pattern,
+ const std::string& mime_type) {
+ const std::string::size_type semicolon = mime_type_pattern.find(';');
+ const std::string::size_type test_semicolon = mime_type.find(';');
+ if (semicolon != std::string::npos) {
+ if (test_semicolon == std::string::npos)
+ return false;
+
+ std::vector<std::string> pattern_parameters;
+ base::SplitString(mime_type_pattern.substr(semicolon + 1),
+ ';', &pattern_parameters);
+
+ std::vector<std::string> test_parameters;
+ base::SplitString(mime_type.substr(test_semicolon + 1),
+ ';', &test_parameters);
+
+ sort(pattern_parameters.begin(), pattern_parameters.end());
+ sort(test_parameters.begin(), test_parameters.end());
+ std::vector<std::string> difference;
+ std::set_difference(pattern_parameters.begin(), pattern_parameters.end(),
+ test_parameters.begin(), test_parameters.end(),
+ std::inserter(difference, difference.begin()));
+
+ return difference.size() == 0;
+ }
+ return true;
+}
+
+// This comparison handles absolute maching and also basic
+// wildcards. The plugin mime types could be:
+// application/x-foo
+// application/*
+// application/*+xml
+// *
+// Also tests mime parameters -- all parameters in the pattern must be present
+// in the tested type for a match to succeed.
bool MimeUtil::MatchesMimeType(const std::string& mime_type_pattern,
const std::string& mime_type) const {
- // verify caller is passing lowercase
+ // Verify caller is passing lowercase strings.
DCHECK_EQ(StringToLowerASCII(mime_type_pattern), mime_type_pattern);
DCHECK_EQ(StringToLowerASCII(mime_type), mime_type);
- // This comparison handles absolute maching and also basic
- // wildcards. The plugin mime types could be:
- // application/x-foo
- // application/*
- // application/*+xml
- // *
if (mime_type_pattern.empty())
return false;
- const std::string::size_type star = mime_type_pattern.find('*');
+ std::string::size_type semicolon = mime_type_pattern.find(';');
+ const std::string base_pattern(mime_type_pattern.substr(0, semicolon));
+ semicolon = mime_type.find(';');
+ const std::string base_type(mime_type.substr(0, semicolon));
+
+ if (base_pattern == "*" || base_pattern == "*/*")
+ return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
- if (star == std::string::npos)
- return mime_type_pattern == mime_type;
+ const std::string::size_type star = base_pattern.find('*');
+ if (star == std::string::npos) {
+ if (base_pattern == base_type)
+ return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
+ else
+ return false;
+ }
// Test length to prevent overlap between |left| and |right|.
- if (mime_type.length() < mime_type_pattern.length() - 1)
+ if (base_type.length() < base_pattern.length() - 1)
return false;
- const std::string left(mime_type_pattern.substr(0, star));
- const std::string right(mime_type_pattern.substr(star + 1));
+ const std::string left(base_pattern.substr(0, star));
+ const std::string right(base_pattern.substr(star + 1));
- if (mime_type.find(left) != 0)
+ if (base_type.find(left) != 0)
return false;
if (!right.empty() &&
- mime_type.rfind(right) != mime_type.length() - right.length())
+ base_type.rfind(right) != base_type.length() - right.length())
return false;
- return true;
+ return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
}
// See http://www.iana.org/assignments/media-types/index.html
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 635b517..225b668 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/basictypes.h"
+#include "base/string_split.h"
#include "base/utf_string_conversions.h"
#include "net/base/mime_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -98,6 +99,46 @@ TEST(MimeUtilTest, MatchesMimeType) {
EXPECT_FALSE(MatchesMimeType("application/*+xml",
"applcation/html+xml"));
EXPECT_FALSE(MatchesMimeType("aaa*aaa", "aaaaa"));
+
+ EXPECT_TRUE(MatchesMimeType("*", "video/x-mpeg;param=val"));
+ EXPECT_TRUE(MatchesMimeType("video/*", "video/x-mpeg;param=val"));
+ EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/mpeg"));
+ EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/mpeg;param=other"));
+ EXPECT_TRUE(MatchesMimeType("video/*;param=val", "video/mpeg;param=val"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg", "video/x-mpeg;param=val"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val",
+ "video/x-mpeg;param=val"));
+ EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param2=val2",
+ "video/x-mpeg;param=val"));
+ EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param2=val2",
+ "video/x-mpeg;param2=val"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val",
+ "video/x-mpeg;param=val;param2=val2"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val;param2=val2",
+ "video/x-mpeg;param=val;param2=val2"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param2=val2;param=val",
+ "video/x-mpeg;param=val;param2=val2"));
+ EXPECT_FALSE(MatchesMimeType("video/x-mpeg;param3=val3;param=val",
+ "video/x-mpeg;param=val;param2=val2"));
+ EXPECT_TRUE(MatchesMimeType("video/x-mpeg;param=val ;param2=val2 ",
+ "video/x-mpeg;param=val;param2=val2"));
+
+ EXPECT_TRUE(MatchesMimeType("*/*;param=val", "video/x-mpeg;param=val"));
+ EXPECT_FALSE(MatchesMimeType("*/*;param=val", "video/x-mpeg;param=val2"));
+
+ EXPECT_TRUE(MatchesMimeType("*", "*"));
+ EXPECT_TRUE(MatchesMimeType("*", "*/*"));
+ EXPECT_TRUE(MatchesMimeType("*/*", "*/*"));
+ EXPECT_TRUE(MatchesMimeType("*/*", "*"));
+ EXPECT_TRUE(MatchesMimeType("video/*", "video/*"));
+ EXPECT_FALSE(MatchesMimeType("video/*", "*/*"));
+ EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/*"));
+ EXPECT_TRUE(MatchesMimeType("video/*;param=val", "video/*;param=val"));
+ EXPECT_FALSE(MatchesMimeType("video/*;param=val", "video/*;param=val2"));
+
+ EXPECT_TRUE(MatchesMimeType("ab*cd", "abxxxcd"));
+ EXPECT_TRUE(MatchesMimeType("ab*cd", "abx/xcd"));
+ EXPECT_TRUE(MatchesMimeType("ab/*cd", "ab/xxxcd"));
}
// Note: codecs should only be a list of 2 or fewer; hence the restriction of