diff --git a/ChangeLog b/ChangeLog index 180490185..eadc1345d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2012-09-07 Wolfgang Sourdeau + * OpenChange/MAPIStoreContext.m (CompleteURLFromMapistoreURI): + mapistore uris are already escaped. + (-getRootFolder:withFID:): all urls are now escaped, both in NSURL + and in NSString forms, whether they are used to return a mapitore + root uri or a indexing record. + * OpenChange/NSString+MAPIStore.m (-stringByReplacingPercentEscapesUsingEncoding:): we now return nil for non-ascii strings. diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index dceed826f..e698c8caf 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -207,7 +207,7 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) [NSString stringWithUTF8String: uri]]; if (![urlString hasSuffix: @"/"]) urlString = [urlString stringByAppendingString: @"/"]; - completeURL = [NSURL URLWithString: [urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; + completeURL = [NSURL URLWithString: urlString]; return completeURL; } @@ -418,25 +418,33 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) MAPIStoreFolder *baseFolder; SOGoFolder *currentFolder; WOContext *woContext; - NSString *path, *urlString; + NSString *path; NSArray *pathComponents; NSUInteger count, max; mapping = [userContext mapping]; if (![mapping urlFromID: newFid]) - { - urlString = [[contextUrl absoluteString] - stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - [mapping registerURL: urlString - withID: newFid]; - } + [mapping registerURL: [contextUrl absoluteString] + withID: newFid]; [userContext activateWithUser: activeUser]; woContext = [userContext woContext]; [self ensureContextFolder]; currentFolder = [self rootSOGoFolder]; [containersBag addObject: currentFolder]; - path = [contextUrl path]; + + /* HACK: + -[NSURL path] returns unescaped strings in theory. In pratice, sometimes + it does, sometimes not. Therefore we use the result of our own + implementation of -[NSString + stringByReplacingPercentEscapeUsingEncoding:], which returns nil if the + original string contains non-ascii chars, from which we can determine + whether the path was unescaped or not. */ + path = [[contextUrl path] + stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + if (!path) + path = [contextUrl path]; + if ([path hasPrefix: @"/"]) path = [path substringFromIndex: 1]; if ([path hasSuffix: @"/"]) @@ -515,7 +523,8 @@ static inline NSURL *CompleteURLFromMapistoreURI (const char *uri) void *rootObject; if (key) - childURL = [NSString stringWithFormat: @"%@%@", folderURL, key]; + childURL = [NSString stringWithFormat: @"%@%@", folderURL, + [key stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; else childURL = folderURL; mapping = [userContext mapping]; diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 8cb57b5ac..faf87f9f0 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -96,14 +96,13 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe { NSURL *folderURL; NSMutableString *pathPrefix; - NSString *path, *escapedURL, *folderName; + NSString *path, *folderName; NSArray *parts; NSUInteger lastPartIdx; MAPIStoreUserContext *userContext; - escapedURL = [[self url] - stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; - folderURL = [NSURL URLWithString: escapedURL]; + folderURL = [NSURL URLWithString: [self url]]; + /* note: -[NSURL path] returns an unescaped representation */ path = [folderURL path]; path = [path substringFromIndex: 1]; if ([path length] > 0) @@ -252,7 +251,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe - (id) lookupFolderByURL: (NSString *) childURL { MAPIStoreObject *foundObject = nil; - NSString *baseURL, *subURL; + NSString *baseURL, *subURL, *part; NSArray *parts; NSUInteger partsCount; @@ -268,7 +267,11 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe partsCount = [parts count]; if ((partsCount == 1) || (partsCount == 2 && [[parts objectAtIndex: 1] length] == 0)) - foundObject = [self lookupFolder: [parts objectAtIndex: 0]]; + { + part = [[parts objectAtIndex: 0] + stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + foundObject = [self lookupFolder: part]; + } } } @@ -339,7 +342,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe partsCount = [parts count]; if (partsCount == 1) { - key = [parts objectAtIndex: 0]; + key = [[parts objectAtIndex: 0] + stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; foundObject = [self lookupFAIMessage: key]; if (!foundObject) foundObject = [self lookupMessage: key]; @@ -405,7 +409,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe if (![baseURL hasSuffix: @"/"]) baseURL = [NSString stringWithFormat: @"%@/", baseURL]; childURL = [NSString stringWithFormat: @"%@%@/", - baseURL, folderKey]; + baseURL, + [folderKey stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; [mapping registerURL: childURL withID: fid]; childFolder = [self lookupFolder: folderKey]; if (childFolder) @@ -1543,8 +1548,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe url = [NSString stringWithFormat: @"%@/", [super url]]; else { - url = [[[context url] absoluteString] - stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + url = [[context url] absoluteString]; if (![url hasSuffix: @"/"]) url = [NSString stringWithFormat: @"%@/", url]; } diff --git a/OpenChange/MAPIStoreMailContext.m b/OpenChange/MAPIStoreMailContext.m index b57ea1949..83dc70e1f 100644 --- a/OpenChange/MAPIStoreMailContext.m +++ b/OpenChange/MAPIStoreMailContext.m @@ -129,7 +129,8 @@ MakeDisplayFolderName (NSString *folderName) for (count = 0; count < 3; count++) { context = talloc_zero (memCtx, struct mapistore_contexts_list); - stringData = [NSString stringWithFormat: @"%@%@", urlBase, folderName[count]]; + stringData = [NSString stringWithFormat: @"%@%@", urlBase, + [folderName[count] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; context->url = [stringData asUnicodeInMemCtx: context]; /* remove "folder" prefix */ stringData = MakeDisplayFolderName (folderName[count]); @@ -152,7 +153,8 @@ MakeDisplayFolderName (NSString *folderName) { context = talloc_zero (memCtx, struct mapistore_contexts_list); currentName = [secondaryFolders objectAtIndex: count]; - stringData = [NSString stringWithFormat: @"%@%@", urlBase, currentName]; + stringData = [NSString stringWithFormat: @"%@%@", + urlBase, [currentName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; context->url = [stringData asUnicodeInMemCtx: context]; stringData = [[currentName substringFromIndex: 6] fromCSSIdentifier]; context->name = [stringData asUnicodeInMemCtx: context]; @@ -185,7 +187,8 @@ MakeDisplayFolderName (NSString *folderName) inContainer: accountFolder]; if ([newFolder create]) mapistoreURI = [NSString stringWithFormat: @"sogo://%@:%@@mail/%@/", - userName, userName, folderName]; + userName, userName, + [folderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; else mapistoreURI = nil; [MAPIApp setUserContext: nil]; diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 9bbaede63..0a44fd3a6 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -1036,7 +1036,8 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) NSUInteger count, max; NGImap4Connection *connection; NGImap4Client *client; - NSString *newURL, *parentDBFolderPath, *childKey, *folderIMAPName, *newFolderIMAPName; + NSString *newURL, *parentDBFolderPath, *childKey, *folderIMAPName, + *urlNamePart, *newFolderIMAPName; NSException *error; MAPIStoreMapping *mapping; NSDictionary *result; @@ -1049,9 +1050,9 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) targetSOGoFolder = [targetFolder sogoObject]; if (isMove) { - newFolderURL = [NSURL - URLWithString: [newFolderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding] - relativeToURL: [targetSOGoFolder imap4URL]]; + urlNamePart = [newFolderName stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + newFolderURL = [NSURL URLWithString: urlNamePart + relativeToURL: [targetSOGoFolder imap4URL]]; error = [[sogoObject imap4Connection] moveMailboxAtURL: folderURL toURL: newFolderURL]; @@ -1062,7 +1063,7 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) rc = MAPISTORE_SUCCESS; mapping = [self mapping]; newURL = [NSString stringWithFormat: @"%@folder%@/", - [targetFolder url], newFolderName]; + [targetFolder url], urlNamePart]; [mapping updateID: [self objectId] withURL: newURL]; parentDBFolderPath = [[targetFolder dbFolder] path]; if (!parentDBFolderPath) diff --git a/OpenChange/MAPIStoreObject.m b/OpenChange/MAPIStoreObject.m index 185f19286..5679ad5ae 100644 --- a/OpenChange/MAPIStoreObject.m +++ b/OpenChange/MAPIStoreObject.m @@ -126,7 +126,7 @@ static Class NSExceptionK, MAPIStoreFolderK; - (NSString *) url { - NSString *containerURL, *format; + NSString *containerURL, *urlName, *format; containerURL = (NSString *) [container url]; if ([containerURL hasSuffix: @"/"]) @@ -134,8 +134,9 @@ static Class NSExceptionK, MAPIStoreFolderK; else format = @"%@/%@"; - return [NSString stringWithFormat: format, - containerURL, [self nameInContainer]]; + urlName = [[self nameInContainer] + stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; + return [NSString stringWithFormat: format, containerURL, urlName]; } /* helpers */