Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Unified Diff: content/browser/download/quarantine_mac.mm

Issue 2352763006: On macOS 10.10+, use NSURL methods in quarantine_mac. (Closed)
Patch Set: Fix logic. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | content/browser/download/quarantine_mac_unittest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/download/quarantine_mac.mm
diff --git a/content/browser/download/quarantine_mac.mm b/content/browser/download/quarantine_mac.mm
index 3ff57743e4a93c57fec8e80ec0b9987f99039686..e3351e2fb9c4230855b95e82b037ed3d6e0d58f4 100644
--- a/content/browser/download/quarantine_mac.mm
+++ b/content/browser/download/quarantine_mac.mm
@@ -4,8 +4,8 @@
#include "content/browser/download/quarantine.h"
-#include <ApplicationServices/ApplicationServices.h>
-#include <Foundation/Foundation.h>
+#import <ApplicationServices/ApplicationServices.h>
+#import <Foundation/Foundation.h>
#include "base/files/file_path.h"
#include "base/logging.h"
@@ -13,9 +13,129 @@
#include "base/mac/mac_logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "url/gurl.h"
+namespace {
+
+// Once Chrome no longer supports macOS 10.9, this code will no longer be
+// necessary. Note that LSCopyItemAttribute was deprecated in macOS 10.8, but
+// the replacement to kLSItemQuarantineProperties did not exist until macOS
+// 10.10.
+#if !defined(MAC_OS_X_VERSION_10_10) || \
+ MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+bool GetQuarantinePropertiesDeprecated(
+ const base::FilePath& file,
+ base::scoped_nsobject<NSMutableDictionary>* properties) {
+ FSRef file_ref;
+ if (!base::mac::FSRefFromPath(file.value(), &file_ref))
+ return false;
+
+ base::ScopedCFTypeRef<CFTypeRef> quarantine_properties;
+ OSStatus status = LSCopyItemAttribute(&file_ref, kLSRolesAll,
+ kLSItemQuarantineProperties, quarantine_properties.InitializeInto());
+ if (status != noErr)
+ return true;
+
+ CFDictionaryRef quarantine_properties_dict =
+ base::mac::CFCast<CFDictionaryRef>(quarantine_properties.get());
+ if (!quarantine_properties_dict) {
+ LOG(WARNING) << "kLSItemQuarantineProperties is not a dictionary on file "
+ << file.value();
+ return false;
+ }
+
+ properties->reset(
+ [base::mac::CFToNSCast(quarantine_properties_dict) mutableCopy]);
+ return true;
+}
+
+bool SetQuarantinePropertiesDeprecated(const base::FilePath& file,
+ NSDictionary* properties) {
+ FSRef file_ref;
+ if (!base::mac::FSRefFromPath(file.value(), &file_ref))
+ return false;
+ OSStatus os_error = LSSetItemAttribute(
+ &file_ref, kLSRolesAll, kLSItemQuarantineProperties, properties);
+ if (os_error != noErr) {
+ OSSTATUS_LOG(WARNING, os_error)
+ << "Unable to set quarantine attributes on file " << file.value();
+ return false;
+ }
+ return true;
+}
+#pragma clang diagnostic pop
+#endif
+
+bool GetQuarantineProperties(
+ const base::FilePath& file,
+ base::scoped_nsobject<NSMutableDictionary>* properties) {
+ base::scoped_nsobject<NSURL> file_url([[NSURL alloc]
+ initFileURLWithPath:base::SysUTF8ToNSString(file.value())]);
+ if (!file_url)
+ return false;
+
+// NSURLQuarantinePropertiesKey is only available on macOS 10.10+.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability"
+ NSError* error = nil;
+ id quarantine_properties = nil;
+ BOOL success = [file_url getResourceValue:&quarantine_properties
+ forKey:NSURLQuarantinePropertiesKey
+ error:&error];
+#pragma clang diagnostic pop
+ if (!success) {
+ std::string error_message(error ? error.description.UTF8String : "");
+ LOG(WARNING) << "Unable to get quarantine attributes for file "
+ << file.value() << ". Error: " << error_message;
+ return false;
+ }
+
+ if (!quarantine_properties)
+ return true;
+
+ NSDictionary* quarantine_properties_dict =
+ base::mac::ObjCCast<NSDictionary>(quarantine_properties);
+ if (!quarantine_properties_dict) {
+ LOG(WARNING) << "Quarantine properties have wrong class: "
+ << [[[quarantine_properties class] description] UTF8String];
+ return false;
+ }
+
+ properties->reset([quarantine_properties_dict mutableCopy]);
+ return true;
+}
+
+bool SetQuarantineProperties(const base::FilePath& file,
+ NSDictionary* properties) {
+ base::scoped_nsobject<NSURL> file_url([[NSURL alloc]
+ initFileURLWithPath:base::SysUTF8ToNSString(file.value())]);
+ if (!file_url)
+ return false;
+
+// NSURLQuarantinePropertiesKey is only available on macOS 10.10+.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability"
+ NSError* error = nil;
+ bool success = [file_url setResourceValue:properties
+ forKey:NSURLQuarantinePropertiesKey
+ error:&error];
+#pragma clang diagnostic pop
+ if (!success) {
+ std::string error_message(error ? error.description.UTF8String : "");
+ LOG(WARNING) << "Unable to set quarantine attributes on file "
+ << file.value() << ". Error: " << error_message;
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
namespace content {
namespace {
@@ -111,27 +231,18 @@ bool AddQuarantineMetadataToFile(const base::FilePath& file,
const GURL& source,
const GURL& referrer) {
base::ThreadRestrictions::AssertIOAllowed();
- FSRef file_ref;
- if (!base::mac::FSRefFromPath(file.value(), &file_ref))
- return false;
-
- NSMutableDictionary* quarantine_properties = nil;
- CFTypeRef quarantine_properties_base = NULL;
- if (LSCopyItemAttribute(&file_ref, kLSRolesAll, kLSItemQuarantineProperties,
- &quarantine_properties_base) == noErr) {
- if (CFGetTypeID(quarantine_properties_base) == CFDictionaryGetTypeID()) {
- // Quarantine properties will already exist if LSFileQuarantineEnabled
- // is on and the file doesn't match an exclusion.
- quarantine_properties =
- [[(NSDictionary*)quarantine_properties_base mutableCopy] autorelease];
- } else {
- LOG(WARNING) << "kLSItemQuarantineProperties is not a dictionary on file "
- << file.value();
- }
- CFRelease(quarantine_properties_base);
+ base::scoped_nsobject<NSMutableDictionary> properties;
+ bool success = false;
+ if (base::mac::IsAtLeastOS10_10()) {
+ success = GetQuarantineProperties(file, &properties);
+ } else {
+ success = GetQuarantinePropertiesDeprecated(file, &properties);
}
- if (!quarantine_properties) {
+ if (!success)
+ return false;
+
+ if (!properties) {
// If there are no quarantine properties, then the file isn't quarantined
// (e.g., because the user has set up exclusions for certain file types).
// We don't want to add any metadata, because that will cause the file to
@@ -143,40 +254,34 @@ bool AddQuarantineMetadataToFile(const base::FilePath& file,
// kLSQuarantineTimeStampKey are set for us (see LSQuarantine.h), so we only
// need to set the values that the OS can't infer.
- if (![quarantine_properties valueForKey:(NSString*)kLSQuarantineTypeKey]) {
+ if (![properties valueForKey:(NSString*)kLSQuarantineTypeKey]) {
CFStringRef type = source.SchemeIsHTTPOrHTTPS()
- ? kLSQuarantineTypeWebDownload
- : kLSQuarantineTypeOtherDownload;
- [quarantine_properties setValue:(NSString*)type
- forKey:(NSString*)kLSQuarantineTypeKey];
+ ? kLSQuarantineTypeWebDownload
+ : kLSQuarantineTypeOtherDownload;
+ [properties setValue:(NSString*)type
+ forKey:(NSString*)kLSQuarantineTypeKey];
}
- if (![quarantine_properties
- valueForKey:(NSString*)kLSQuarantineOriginURLKey] &&
+ if (![properties valueForKey:(NSString*)kLSQuarantineOriginURLKey] &&
referrer.is_valid()) {
NSString* referrer_url =
[NSString stringWithUTF8String:referrer.spec().c_str()];
- [quarantine_properties setValue:referrer_url
- forKey:(NSString*)kLSQuarantineOriginURLKey];
+ [properties setValue:referrer_url
+ forKey:(NSString*)kLSQuarantineOriginURLKey];
}
- if (![quarantine_properties valueForKey:(NSString*)kLSQuarantineDataURLKey] &&
+ if (![properties valueForKey:(NSString*)kLSQuarantineDataURLKey] &&
source.is_valid()) {
NSString* origin_url =
[NSString stringWithUTF8String:source.spec().c_str()];
- [quarantine_properties setValue:origin_url
- forKey:(NSString*)kLSQuarantineDataURLKey];
+ [properties setValue:origin_url forKey:(NSString*)kLSQuarantineDataURLKey];
}
- OSStatus os_error =
- LSSetItemAttribute(&file_ref, kLSRolesAll, kLSItemQuarantineProperties,
- quarantine_properties);
- if (os_error != noErr) {
- OSSTATUS_LOG(WARNING, os_error)
- << "Unable to set quarantine attributes on file " << file.value();
- return false;
+ if (base::mac::IsAtLeastOS10_10()) {
+ return SetQuarantineProperties(file, properties);
+ } else {
+ return SetQuarantinePropertiesDeprecated(file, properties);
}
- return true;
}
} // namespace
« no previous file with comments | « no previous file | content/browser/download/quarantine_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698