diff --git a/Signal/src/ViewControllers/MessagesViewController.m b/Signal/src/ViewControllers/MessagesViewController.m index 39dfe7f67..dbcd6d42f 100644 --- a/Signal/src/ViewControllers/MessagesViewController.m +++ b/Signal/src/ViewControllers/MessagesViewController.m @@ -2182,7 +2182,7 @@ typedef enum : NSUInteger { - (void)showAttachmentDocumentPicker { - NSString *allItems = (__bridge NSString *)kUTTypeData; + NSString *allItems = (__bridge NSString *)kUTTypeItem; NSArray *documentTypes = @[ allItems ]; // UIDocumentPickerModeImport copies to a temp file within our container. // It uses more memory than "open" but lets us avoid working with security scoped URLs. @@ -2209,13 +2209,45 @@ typedef enum : NSUInteger { NSData *attachmentData = [NSData dataWithContentsOfURL:url]; NSString *type; - NSError *error; - [url getResourceValue:&type forKey:NSURLTypeIdentifierKey error:&error]; - if (error) { - DDLogError(@"%@ Determining type of picked document at url: %@ failed with error: %@", self.tag, url, error); + NSError *typeError; + [url getResourceValue:&type forKey:NSURLTypeIdentifierKey error:&typeError]; + if (typeError) { + DDLogError( + @"%@ Determining type of picked document at url: %@ failed with error: %@", self.tag, url, typeError); OWSAssert(NO); } + NSNumber *isDirectory; + NSError *isDirectoryError; + [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&isDirectoryError]; + if (isDirectoryError) { + DDLogError(@"%@ Determining if picked document at url: %@ was a directory failed with error: %@", + self.tag, + url, + isDirectoryError); + OWSAssert(NO); + } else if ([isDirectory boolValue]) { + DDLogInfo(@"%@ User picked directory at url: %@", self.tag, url); + UIAlertController *alertController = [UIAlertController + alertControllerWithTitle: + NSLocalizedString(@"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE", + @"Alert title when picking a document fails because user picked a directory/bundle") + message: + NSLocalizedString(@"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_BODY", + @"Alert body when picking a document fails because user picked a directory/bundle") + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"DISMISS_BUTTON_TEXT", nil) + style:UIAlertActionStyleCancel + handler:nil]; + [alertController addAction:dismissAction]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self presentViewController:alertController animated:YES completion:nil]; + }); + return; + } + if (!type) { DDLogDebug(@"%@ falling back to default filetype for picked document at url: %@", self.tag, url); OWSAssert(NO); diff --git a/Signal/src/ViewControllers/SignalAttachment.swift b/Signal/src/ViewControllers/SignalAttachment.swift index 76e89810c..e4f38f65d 100644 --- a/Signal/src/ViewControllers/SignalAttachment.swift +++ b/Signal/src/ViewControllers/SignalAttachment.swift @@ -12,7 +12,6 @@ enum SignalAttachmentError: Error { case couldNotParseImage case couldNotConvertToJpeg case invalidFileFormat - case unknownType } extension SignalAttachmentError: LocalizedError { @@ -30,8 +29,6 @@ extension SignalAttachmentError: LocalizedError { return NSLocalizedString("ATTACHMENT_ERROR_COULD_NOT_CONVERT_TO_JPEG", comment: "Attachment error message for image attachments which could not be converted to JPEG") case .invalidFileFormat: return NSLocalizedString("ATTACHMENT_ERROR_INVALID_FILE_FORMAT", comment: "Attachment error message for attachments with an invalid file format") - case .unknownType: - return NSLocalizedString("ATTACHMENT_ERROR_UNKNOWN_TYPE", comment: "Attachment error message for attachments with an invalid file format") } } } @@ -114,10 +111,6 @@ class SignalAttachment: NSObject { self.dataUTI = dataUTI self.filename = filename super.init() - - if self.mimeType == nil { - error = .unknownType - } } // MARK: Methods @@ -174,7 +167,7 @@ class SignalAttachment: NSObject { // Returns the MIME type for this attachment or nil if no MIME type // can be identified. - var mimeType: String? { + var mimeType: String { if dataUTI == SignalAttachment.kOversizeTextAttachmentUTI { return OWSMimeTypeOversizeTextMessage } @@ -182,7 +175,7 @@ class SignalAttachment: NSObject { return OWSMimeTypeUnknownForTests } guard let mimeType = UTTypeCopyPreferredTagWithClass(dataUTI as CFString, kUTTagClassMIMEType) else { - return nil + return OWSMimeTypeApplicationOctetStream } return mimeType.takeRetainedValue() as String } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 5b985982d..a4358a607 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -106,6 +106,12 @@ /* Alert title when picking a document fails for an unknown reason */ "ATTACHMENT_PICKER_DOCUMENTS_FAILED_ALERT_TITLE" = "Failed to choose document."; +/* Alert body when picking a document fails because user picked a directory/bundle */ +"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_BODY" = "Signal can't handle that file as is. Try zipping it before sending."; + +/* Alert title when picking a document fails because user picked a directory/bundle */ +"ATTACHMENT_PICKER_DOCUMENTS_PICKED_DIRECTORY_FAILED_ALERT_TITLE" = "Unsupported File"; + /* An explanation of the consequences of blocking another user. */ "BLOCK_BEHAVIOR_EXPLANATION" = "Blocked users will not be able to call you or send you messages.";