summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-08 22:12:44 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-08 22:12:44 +0000
commit01651e6f4349b80390493c181df91a3c7b7d2171 (patch)
treeca41deb688a348bc56119c42c227cee2b2be5db5 /net
parent76e80f16f492580ba42293902ef3a56034a477fb (diff)
downloadchromium_src-01651e6f4349b80390493c181df91a3c7b7d2171.zip
chromium_src-01651e6f4349b80390493c181df91a3c7b7d2171.tar.gz
chromium_src-01651e6f4349b80390493c181df91a3c7b7d2171.tar.bz2
Get file extension synonyms from the OS, fix so that if one synonym is safe they all are.
BUG=126088 TEST=as in bug Review URL: https://chromiumcodereview.appspot.com/10379011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135925 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/mime_util.cc10
-rw-r--r--net/base/net_util.cc18
-rw-r--r--net/base/net_util_unittest.cc22
-rw-r--r--net/base/platform_mime_util.h14
-rw-r--r--net/base/platform_mime_util_linux.cc12
-rw-r--r--net/base/platform_mime_util_mac.mm (renamed from net/base/platform_mime_util_mac.cc)39
-rw-r--r--net/base/platform_mime_util_win.cc14
-rw-r--r--net/net.gyp3
8 files changed, 114 insertions, 18 deletions
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index 8a9709f..8ff58e6d 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -688,10 +688,9 @@ void GetExtensionsHelper(const char** standard_types,
size_t standard_types_len,
const std::string& leading_mime_type,
base::hash_set<FilePath::StringType>* extensions) {
- FilePath::StringType extension;
for (size_t i = 0; i < standard_types_len; ++i) {
- if (GetPreferredExtensionForMimeType(standard_types[i], &extension))
- extensions->insert(extension);
+ g_mime_util.Get().GetPlatformExtensionsForMimeType(standard_types[i],
+ extensions);
}
// Also look up the extensions from hard-coded mappings in case that some
@@ -744,9 +743,8 @@ void GetVideoExtensions(std::vector<FilePath::StringType>* extensions) {
void GetExtensionsForMimeType(const std::string& mime_type,
std::vector<FilePath::StringType>* extensions) {
base::hash_set<FilePath::StringType> unique_extensions;
- FilePath::StringType extension;
- if (GetPreferredExtensionForMimeType(mime_type, &extension))
- unique_extensions.insert(extension);
+ g_mime_util.Get().GetPlatformExtensionsForMimeType(mime_type,
+ &unique_extensions);
// Also look up the extensions from hard-coded mappings in case that some
// supported extensions are not registered in the system registry, like ogg.
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index b9e7ad1..967eb03 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -1036,16 +1036,26 @@ void EnsureSafeExtension(const std::string& mime_type,
extension.erase(extension.begin()); // Erase preceding '.'.
if ((ignore_extension || extension.empty()) && !mime_type.empty()) {
- FilePath::StringType mime_extension;
+ FilePath::StringType preferred_mime_extension;
+ std::vector<FilePath::StringType> all_mime_extensions;
// The GetPreferredExtensionForMimeType call will end up going to disk. Do
// this on another thread to avoid slowing the IO thread.
// http://crbug.com/61827
// TODO(asanka): Remove this ScopedAllowIO once all callers have switched
// over to IO safe threads.
base::ThreadRestrictions::ScopedAllowIO allow_io;
- net::GetPreferredExtensionForMimeType(mime_type, &mime_extension);
- if (!mime_extension.empty())
- extension = mime_extension;
+ net::GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension);
+ net::GetExtensionsForMimeType(mime_type, &all_mime_extensions);
+ // If the existing extension is in the list of valid extensions for the
+ // given type, use it. This avoids doing things like pointlessly renaming
+ // "foo.jpg" to "foo.jpeg".
+ if (std::find(all_mime_extensions.begin(),
+ all_mime_extensions.end(),
+ extension) != all_mime_extensions.end()) {
+ // leave |extension| alone
+ } else if (!preferred_mime_extension.empty()) {
+ extension = preferred_mime_extension;
+ }
}
#if defined(OS_WIN)
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 6650863..67d202c 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -891,6 +891,17 @@ TEST(NetUtilTest, GenerateSafeFileName) {
FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"),
FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-")
},
+ // Allow extension synonyms.
+ {
+ "image/jpeg",
+ FILE_PATH_LITERAL("C:\\foo\\bar.jpg"),
+ FILE_PATH_LITERAL("C:\\foo\\bar.jpg")
+ },
+ {
+ "image/jpeg",
+ FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"),
+ FILE_PATH_LITERAL("C:\\foo\\bar.jpeg")
+ },
#else // !defined(OS_WIN)
{
"text/html",
@@ -937,6 +948,17 @@ TEST(NetUtilTest, GenerateSafeFileName) {
FILE_PATH_LITERAL("/foo/con"),
FILE_PATH_LITERAL("/foo/con.html")
},
+ // Allow extension synonyms.
+ {
+ "image/jpeg",
+ FILE_PATH_LITERAL("/bar.jpg"),
+ FILE_PATH_LITERAL("/bar.jpg")
+ },
+ {
+ "image/jpeg",
+ FILE_PATH_LITERAL("/bar.jpeg"),
+ FILE_PATH_LITERAL("/bar.jpeg")
+ },
#endif // !defined(OS_WIN)
};
diff --git a/net/base/platform_mime_util.h b/net/base/platform_mime_util.h
index e2b9589..6e124c1 100644
--- a/net/base/platform_mime_util.h
+++ b/net/base/platform_mime_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,17 +9,25 @@
#include <string>
#include "base/file_path.h"
+#include "base/hash_tables.h"
namespace net {
-// Encapsulates the platform-specific functionality in mime_util
+// Encapsulates the platform-specific functionality in mime_util.
class PlatformMimeUtil {
public:
// See documentation for base::GetPreferredExtensionForMimeType [mime_util.h]
bool GetPreferredExtensionForMimeType(const std::string& mime_type,
FilePath::StringType* extension) const;
- protected:
+ // Adds all the extensions that the platform associates with the type
+ // |mime_type| to the set |extensions|. Returns at least the value returned
+ // by GetPreferredExtensionForMimeType.
+ void GetPlatformExtensionsForMimeType(
+ const std::string& mime_type,
+ base::hash_set<FilePath::StringType>* extensions) const;
+
+ protected:
// Get the mime type (if any) that is associated with the file extension.
// Returns true if a corresponding mime type exists.
bool GetPlatformMimeTypeFromExtension(const FilePath::StringType& ext,
diff --git a/net/base/platform_mime_util_linux.cc b/net/base/platform_mime_util_linux.cc
index 564dc31..f26b453 100644
--- a/net/base/platform_mime_util_linux.cc
+++ b/net/base/platform_mime_util_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -91,7 +91,7 @@ bool PlatformMimeUtil::GetPreferredExtensionForMimeType(
}
}
- // TODO(dhg): Fix this the right way by implementing whats said below.
+ // TODO(dhg): Fix this the right way by implementing what's said below.
// Unlike GetPlatformMimeTypeFromExtension, this method doesn't have a
// default list that it uses, but for now we are also returning false since
// this doesn't really matter as much under Linux.
@@ -104,4 +104,12 @@ bool PlatformMimeUtil::GetPreferredExtensionForMimeType(
return false;
}
+void PlatformMimeUtil::GetPlatformExtensionsForMimeType(
+ const std::string& mime_type,
+ base::hash_set<FilePath::StringType>* extensions) const {
+ FilePath::StringType ext;
+ if (GetPreferredExtensionForMimeType(mime_type, &ext))
+ extensions->insert(ext);
+}
+
} // namespace net
diff --git a/net/base/platform_mime_util_mac.cc b/net/base/platform_mime_util_mac.mm
index 931973f..a95a503 100644
--- a/net/base/platform_mime_util_mac.cc
+++ b/net/base/platform_mime_util_mac.mm
@@ -1,16 +1,26 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/base/platform_mime_util.h"
#include <CoreServices/CoreServices.h>
+#import <Foundation/Foundation.h>
#include <string>
+#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
+#import "base/memory/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
+// SPI declaration; see the commentary in GetPlatformExtensionsForMimeType.
+
+@interface NSURLFileTypeMappings : NSObject
++ (NSURLFileTypeMappings*)sharedMappings;
+- (NSArray*)extensionsForMIMEType:(NSString*)mimeType;
+@end
+
namespace net {
bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
@@ -58,4 +68,31 @@ bool PlatformMimeUtil::GetPreferredExtensionForMimeType(
return true;
}
+void PlatformMimeUtil::GetPlatformExtensionsForMimeType(
+ const std::string& mime_type,
+ base::hash_set<FilePath::StringType>* extensions) const {
+ // There is no API for this that uses UTIs. The WebKitSystemInterface call
+ // WKGetExtensionsForMIMEType() is a thin wrapper around
+ // [[NSURLFileTypeMappings sharedMappings] extensionsForMIMEType:], which is
+ // used by Firefox as well.
+ //
+ // See:
+ // http://mxr.mozilla.org/mozilla-central/search?string=extensionsForMIMEType
+ // http://www.openradar.me/11384153
+ // rdar://11384153
+ NSArray* extensions_list =
+ [[NSURLFileTypeMappings sharedMappings]
+ extensionsForMIMEType:base::SysUTF8ToNSString(mime_type)];
+
+ if (extensions_list) {
+ for (NSString* extension in extensions_list)
+ extensions->insert(base::SysNSStringToUTF8(extension));
+ } else {
+ // Huh? Give up.
+ FilePath::StringType ext;
+ if (GetPreferredExtensionForMimeType(mime_type, &ext))
+ extensions->insert(ext);
+ }
+}
+
} // namespace net
diff --git a/net/base/platform_mime_util_win.cc b/net/base/platform_mime_util_win.cc
index 7a8f7d9..7b65965 100644
--- a/net/base/platform_mime_util_win.cc
+++ b/net/base/platform_mime_util_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -39,4 +39,16 @@ bool PlatformMimeUtil::GetPreferredExtensionForMimeType(
return true;
}
+void PlatformMimeUtil::GetPlatformExtensionsForMimeType(
+ const std::string& mime_type,
+ base::hash_set<FilePath::StringType>* extensions) const {
+ // Multiple extensions could have the given mime type specified as their types
+ // in their 'HKCR\.<extension>\Content Type' keys. Iterating all the HKCR
+ // entries, though, is wildly impractical. Cheat by returning just the
+ // preferred extension.
+ FilePath::StringType ext;
+ if (GetPreferredExtensionForMimeType(mime_type, &ext))
+ extensions->insert(ext);
+}
+
} // namespace net
diff --git a/net/net.gyp b/net/net.gyp
index a78e5ed..ebad7cb9 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -212,7 +212,7 @@
'base/platform_mime_util.h',
# TODO(tc): gnome-vfs? xdgmime? /etc/mime.types?
'base/platform_mime_util_linux.cc',
- 'base/platform_mime_util_mac.cc',
+ 'base/platform_mime_util_mac.mm',
'base/platform_mime_util_win.cc',
'base/prioritized_dispatcher.cc',
'base/prioritized_dispatcher.h',
@@ -976,6 +976,7 @@
],
'link_settings': {
'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
'$(SDKROOT)/System/Library/Frameworks/SystemConfiguration.framework',
'$(SDKROOT)/usr/lib/libresolv.dylib',