From a8432bdec98a105b1527cad6cbd97f2e7a5fbec4 Mon Sep 17 00:00:00 2001 From: "vladimir@pobox.com" Date: Thu, 20 Mar 2008 15:57:44 -0700 Subject: [PATCH] b=414201, [relanding] JPEG images dragged to Finder have file extension changed to .jfif; r=stan,sr=shaver,a=beltzner --- docshell/test/unit/test_bug414201_jfif.js | 58 +++++++++++++++++++ .../exthandler/mac/nsInternetConfigService.mm | 53 +++++++++++++++-- 2 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 docshell/test/unit/test_bug414201_jfif.js diff --git a/docshell/test/unit/test_bug414201_jfif.js b/docshell/test/unit/test_bug414201_jfif.js new file mode 100644 index 000000000000..a29a52b0d5fa --- /dev/null +++ b/docshell/test/unit/test_bug414201_jfif.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vladimir Vukicevic + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Test for bug 414201 + */ + +function run_test() +{ + var ms = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService); + + /* Test a few common image types to make sure that they get the right extension */ + var types = { + "image/jpeg": "jpg", + "image/gif": "gif", + "image/png": "png" + }; + + /* Check whether the primary extension is what we'd expect */ + for (var mimetype in types) { + var ext = types[mimetype]; + do_check_true (ms.getFromTypeAndExtension(mimetype, null).primaryExtension.toLowerCase() == ext); + } +} diff --git a/uriloader/exthandler/mac/nsInternetConfigService.mm b/uriloader/exthandler/mac/nsInternetConfigService.mm index 3487ad9c254f..427445ac32b5 100644 --- a/uriloader/exthandler/mac/nsInternetConfigService.mm +++ b/uriloader/exthandler/mac/nsInternetConfigService.mm @@ -53,7 +53,22 @@ #include "nsMimeTypes.h" #import +#import +#import +/* This is an undocumented interface that seems to exist at least in 10.4 and 10.5 */ +@class NSURLFileTypeMappingsInternal; + +@interface NSURLFileTypeMappings : NSObject +{ + NSURLFileTypeMappingsInternal *_internal; +} + ++ (NSURLFileTypeMappings*)sharedMappings; +- (NSString*)MIMETypeForExtension:(NSString*)fp8; +- (NSString*)preferredExtensionForMIMEType:(NSString*)fp8; +- (NSArray*)extensionsForMIMEType:(NSString*)fp8; +@end // helper converter function..... static void ConvertCharStringToStr255(const char* inString, Str255& outString) @@ -289,6 +304,8 @@ nsresult nsInternetConfigService::GetMappingForMIMEType(const char *mimetype, co nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo) { + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + // create a mime info object and we'll fill it in based on the values from IC mapping entry nsresult rv = NS_OK; nsRefPtr info (new nsMIMEInfoMac()); @@ -308,11 +325,35 @@ nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIM else info->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM)); } - - // convert entry.extension which is a Str255 - // don't forget to remove the '.' in front of the file extension.... - nsCAutoString temp((char *)&entry.extension[2], entry.extension[0] > 0 ? (int)entry.extension[0]-1 : 0); - info->AppendExtension(temp); + + nsCAutoString temp; + + /* The internet config service seems to return the first extension + * from the map's list; however, that first extension is sometimes + * not the best one to use. Specifically, for image/jpeg, the + * internet config service will return "jfif", whereas the + * preferred extension is really "jpg". So, don't believe IC's + * lies, and ask NSURLFileTypeMappings instead (see bug 414201). + */ + NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings]; + NSString *mimeStr = [NSString stringWithCString:mimetype.get() encoding:NSASCIIStringEncoding]; + NSString *realExtension = map ? [map preferredExtensionForMIMEType:mimeStr] : NULL; + [mimeStr release]; + + if (realExtension) { + temp.Assign([realExtension cStringUsingEncoding:NSASCIIStringEncoding]); + + info->AppendExtension(temp); + + [realExtension release]; + } else { + // convert entry.extension which is a Str255 + // don't forget to remove the '.' in front of the file extension.... + temp.Assign((char *)&entry.extension[2], entry.extension[0] > 0 ? (int)entry.extension[0]-1 : 0); + + info->AppendExtension(temp); + } + info->SetMacType(entry.fileType); info->SetMacCreator(entry.fileCreator); temp.Assign((char *) &entry.entryName[1], entry.entryName[0]); @@ -350,6 +391,8 @@ nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIM rv = NS_ERROR_FAILURE; return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } /* void FillInMIMEInfo (in string mimetype, in string fileExtension, out nsIMIMEInfo mimeinfo); */