diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-08 22:12:44 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-08 22:12:44 +0000 |
commit | 01651e6f4349b80390493c181df91a3c7b7d2171 (patch) | |
tree | ca41deb688a348bc56119c42c227cee2b2be5db5 /net | |
parent | 76e80f16f492580ba42293902ef3a56034a477fb (diff) | |
download | chromium_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.cc | 10 | ||||
-rw-r--r-- | net/base/net_util.cc | 18 | ||||
-rw-r--r-- | net/base/net_util_unittest.cc | 22 | ||||
-rw-r--r-- | net/base/platform_mime_util.h | 14 | ||||
-rw-r--r-- | net/base/platform_mime_util_linux.cc | 12 | ||||
-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.cc | 14 | ||||
-rw-r--r-- | net/net.gyp | 3 |
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', |