Pick out additional fixes, functionality to SecurityBookmarkFileAccess
Match the state of this class with the current state of the macOS sandbox PR Signed-off-by: Kenneth Chew <79120643+kthchew@users.noreply.github.com>
This commit is contained in:
@@ -39,9 +39,12 @@ class SecurityBookmarkFileAccess {
|
|||||||
/// Contains URLs that are currently being accessed.
|
/// Contains URLs that are currently being accessed.
|
||||||
NSMutableSet* m_activeURLs;
|
NSMutableSet* m_activeURLs;
|
||||||
|
|
||||||
|
bool m_readOnly;
|
||||||
|
|
||||||
NSURL* securityScopedBookmarkToNSURL(QByteArray& bookmark, bool& isStale);
|
NSURL* securityScopedBookmarkToNSURL(QByteArray& bookmark, bool& isStale);
|
||||||
public:
|
public:
|
||||||
SecurityBookmarkFileAccess();
|
/// \param readOnly A boolean indicating whether the bookmark should be read-only.
|
||||||
|
SecurityBookmarkFileAccess(bool readOnly = false);
|
||||||
~SecurityBookmarkFileAccess();
|
~SecurityBookmarkFileAccess();
|
||||||
|
|
||||||
/// Get a security scoped bookmark from a URL.
|
/// Get a security scoped bookmark from a URL.
|
||||||
@@ -78,6 +81,9 @@ public:
|
|||||||
/// \return A boolean indicating whether the bookmark was successfully accessed.
|
/// \return A boolean indicating whether the bookmark was successfully accessed.
|
||||||
bool startUsingSecurityScopedBookmark(QByteArray& bookmark, bool& isStale);
|
bool startUsingSecurityScopedBookmark(QByteArray& bookmark, bool& isStale);
|
||||||
void stopUsingSecurityScopedBookmark(QByteArray& bookmark);
|
void stopUsingSecurityScopedBookmark(QByteArray& bookmark);
|
||||||
|
|
||||||
|
/// Returns true if access to the `path` is currently being maintained by this object.
|
||||||
|
bool isAccessingPath(const QString& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FILEACCESS_H
|
#endif //FILEACCESS_H
|
||||||
|
|||||||
@@ -29,25 +29,41 @@ QByteArray SecurityBookmarkFileAccess::urlToSecurityScopedBookmark(const QUrl& u
|
|||||||
|
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
NSURL* nsurl = [url.toNSURL() absoluteURL];
|
NSURL* nsurl = [url.toNSURL() absoluteURL];
|
||||||
|
NSData* bookmark;
|
||||||
if ([m_paths objectForKey:[nsurl path]]) {
|
if ([m_paths objectForKey:[nsurl path]]) {
|
||||||
return QByteArray::fromNSData(m_paths[[nsurl path]]);
|
bookmark = m_paths[[nsurl path]];
|
||||||
|
} else {
|
||||||
|
bookmark = [nsurl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope |
|
||||||
|
(m_readOnly ? NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess : 0)
|
||||||
|
includingResourceValuesForKeys:nil
|
||||||
|
relativeToURL:nil
|
||||||
|
error:&error];
|
||||||
}
|
}
|
||||||
[m_activeURLs addObject:nsurl];
|
|
||||||
NSData* bookmark = [nsurl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
|
|
||||||
includingResourceValuesForKeys:nil
|
|
||||||
relativeToURL:nil
|
|
||||||
error:&error];
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove/reapply access to ensure that write access is immediately cut off for read-only bookmarks
|
||||||
|
// sometimes you need to call this twice to actually stop access (extra calls aren't harmful)
|
||||||
|
[nsurl stopAccessingSecurityScopedResource];
|
||||||
|
[nsurl stopAccessingSecurityScopedResource];
|
||||||
|
nsurl = [NSURL URLByResolvingBookmarkData:bookmark
|
||||||
|
options:NSURLBookmarkResolutionWithSecurityScope |
|
||||||
|
(m_readOnly ? NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess : 0)
|
||||||
|
relativeToURL:nil
|
||||||
|
bookmarkDataIsStale:nil
|
||||||
|
error:&error];
|
||||||
m_paths[[nsurl path]] = bookmark;
|
m_paths[[nsurl path]] = bookmark;
|
||||||
m_bookmarks[bookmark] = nsurl;
|
m_bookmarks[bookmark] = nsurl;
|
||||||
[m_activeURLs addObject:nsurl];
|
|
||||||
|
|
||||||
return QByteArray::fromNSData(bookmark);
|
QByteArray qBookmark = QByteArray::fromNSData(bookmark);
|
||||||
|
bool isStale = false;
|
||||||
|
startUsingSecurityScopedBookmark(qBookmark, isStale);
|
||||||
|
|
||||||
|
return qBookmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityBookmarkFileAccess::SecurityBookmarkFileAccess()
|
SecurityBookmarkFileAccess::SecurityBookmarkFileAccess(bool readOnly) : m_readOnly(readOnly)
|
||||||
{
|
{
|
||||||
m_bookmarks = [NSMutableDictionary new];
|
m_bookmarks = [NSMutableDictionary new];
|
||||||
m_paths = [NSMutableDictionary new];
|
m_paths = [NSMutableDictionary new];
|
||||||
@@ -59,9 +75,6 @@ SecurityBookmarkFileAccess::~SecurityBookmarkFileAccess()
|
|||||||
for (NSURL* url : m_activeURLs) {
|
for (NSURL* url : m_activeURLs) {
|
||||||
[url stopAccessingSecurityScopedResource];
|
[url stopAccessingSecurityScopedResource];
|
||||||
}
|
}
|
||||||
[m_bookmarks release];
|
|
||||||
[m_paths release];
|
|
||||||
[m_activeURLs release];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray SecurityBookmarkFileAccess::pathToSecurityScopedBookmark(const QString& path)
|
QByteArray SecurityBookmarkFileAccess::pathToSecurityScopedBookmark(const QString& path)
|
||||||
@@ -74,7 +87,8 @@ NSURL* SecurityBookmarkFileAccess::securityScopedBookmarkToNSURL(QByteArray& boo
|
|||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
BOOL localStale = NO;
|
BOOL localStale = NO;
|
||||||
NSURL* nsurl = [NSURL URLByResolvingBookmarkData:bookmark.toNSData()
|
NSURL* nsurl = [NSURL URLByResolvingBookmarkData:bookmark.toNSData()
|
||||||
options:NSURLBookmarkResolutionWithSecurityScope
|
options:NSURLBookmarkResolutionWithSecurityScope |
|
||||||
|
(m_readOnly ? NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess : 0)
|
||||||
relativeToURL:nil
|
relativeToURL:nil
|
||||||
bookmarkDataIsStale:&localStale
|
bookmarkDataIsStale:&localStale
|
||||||
error:&error];
|
error:&error];
|
||||||
@@ -83,18 +97,21 @@ NSURL* SecurityBookmarkFileAccess::securityScopedBookmarkToNSURL(QByteArray& boo
|
|||||||
}
|
}
|
||||||
isStale = localStale;
|
isStale = localStale;
|
||||||
if (isStale) {
|
if (isStale) {
|
||||||
NSData* nsBookmark = [nsurl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
|
NSData* nsBookmark = [nsurl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope |
|
||||||
|
(m_readOnly ? NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess : 0)
|
||||||
includingResourceValuesForKeys:nil
|
includingResourceValuesForKeys:nil
|
||||||
relativeToURL:nil
|
relativeToURL:nil
|
||||||
error:&error];
|
error:&error];
|
||||||
if (error) {
|
if (error) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
m_paths[[nsurl path]] = nsBookmark;
|
|
||||||
m_bookmarks[nsBookmark] = nsurl;
|
|
||||||
bookmark = QByteArray::fromNSData(nsBookmark);
|
bookmark = QByteArray::fromNSData(nsBookmark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSData* nsBookmark = bookmark.toNSData();
|
||||||
|
m_paths[[nsurl path]] = nsBookmark;
|
||||||
|
m_bookmarks[nsBookmark] = nsurl;
|
||||||
|
|
||||||
return nsurl;
|
return nsurl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +129,12 @@ QUrl SecurityBookmarkFileAccess::securityScopedBookmarkToURL(QByteArray& bookmar
|
|||||||
|
|
||||||
bool SecurityBookmarkFileAccess::startUsingSecurityScopedBookmark(QByteArray& bookmark, bool& isStale)
|
bool SecurityBookmarkFileAccess::startUsingSecurityScopedBookmark(QByteArray& bookmark, bool& isStale)
|
||||||
{
|
{
|
||||||
NSURL* url = [m_bookmarks objectForKey:bookmark.toNSData()] ? m_bookmarks[bookmark.toNSData()] : securityScopedBookmarkToNSURL(bookmark, isStale);
|
NSURL* url = [m_bookmarks objectForKey:bookmark.toNSData()] ? m_bookmarks[bookmark.toNSData()]
|
||||||
|
: securityScopedBookmarkToNSURL(bookmark, isStale);
|
||||||
if ([m_activeURLs containsObject:url])
|
if ([m_activeURLs containsObject:url])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
[url stopAccessingSecurityScopedResource];
|
||||||
if ([url startAccessingSecurityScopedResource]) {
|
if ([url startAccessingSecurityScopedResource]) {
|
||||||
[m_activeURLs addObject:url];
|
[m_activeURLs addObject:url];
|
||||||
return true;
|
return true;
|
||||||
@@ -131,8 +150,23 @@ void SecurityBookmarkFileAccess::stopUsingSecurityScopedBookmark(QByteArray& boo
|
|||||||
|
|
||||||
if ([m_activeURLs containsObject:url]) {
|
if ([m_activeURLs containsObject:url]) {
|
||||||
[url stopAccessingSecurityScopedResource];
|
[url stopAccessingSecurityScopedResource];
|
||||||
|
[url stopAccessingSecurityScopedResource];
|
||||||
|
|
||||||
[m_activeURLs removeObject:url];
|
[m_activeURLs removeObject:url];
|
||||||
[m_bookmarks removeObjectForKey:bookmark.toNSData()];
|
|
||||||
[m_paths removeObjectForKey:[url path]];
|
[m_paths removeObjectForKey:[url path]];
|
||||||
|
[m_bookmarks removeObjectForKey:bookmark.toNSData()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SecurityBookmarkFileAccess::isAccessingPath(const QString& path)
|
||||||
|
{
|
||||||
|
NSData* bookmark = [m_paths objectForKey:path.toNSString()];
|
||||||
|
if (!bookmark && path.endsWith('/')) {
|
||||||
|
bookmark = [m_paths objectForKey:path.left(path.length() - 1).toNSString()];
|
||||||
|
}
|
||||||
|
if (!bookmark) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NSURL* url = [m_bookmarks objectForKey:bookmark];
|
||||||
|
return [m_activeURLs containsObject:url];
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user