summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@digia.com>2013-11-06 13:09:50 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-08 10:35:38 (GMT)
commit07ecdc01a2b369fe330d723af1a00845c0932834 (patch)
tree9e71b6d47b0a1fa44bb6d92b94ba0b4272a684e6 /src
parent512a1ce0698d370c313bb561bbf078935fa0342e (diff)
downloadQt-07ecdc01a2b369fe330d723af1a00845c0932834.zip
Qt-07ecdc01a2b369fe330d723af1a00845c0932834.tar.gz
Qt-07ecdc01a2b369fe330d723af1a00845c0932834.tar.bz2
Cocoa File Dialog: Remove sandbox-ufriendly QDir::entryList() call
QDir::entryList() uses QDirIterator, which itself uses QFileSystemEngine, and whose backend uses POSIX API in a relatively liberal way. This is a backport of Qt 5's Ia872b9b1244f7b390d173a498011379b9309b3c6. Task-number: QTBUG-34012 Change-Id: I0a17359510e7623b4ee53dd86bb5bdc39785600e Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm66
1 files changed, 48 insertions, 18 deletions
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 77a2ac5..15a2e70 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -291,6 +291,22 @@ QT_USE_NAMESPACE
contextInfo:nil];
}
+- (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir
+{
+ CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filename, kCFURLPOSIXPathStyle, isDir);
+ CFBooleanRef isHidden;
+ Boolean errorOrHidden = false;
+ if (!CFURLCopyResourcePropertyForKey(url, kCFURLIsHiddenKey, &isHidden, NULL)) {
+ errorOrHidden = true;
+ } else {
+ if (CFBooleanGetValue(isHidden))
+ errorOrHidden = true;
+ CFRelease(isHidden);
+ }
+ CFRelease(url);
+ return errorOrHidden;
+}
+
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
{
Q_UNUSED(sender);
@@ -299,8 +315,13 @@ QT_USE_NAMESPACE
return NO;
// Always accept directories regardless of their names (unless it is a bundle):
- BOOL isDir;
- if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) {
+ NSFileManager *fm = [NSFileManager defaultManager];
+ NSDictionary *fileAttrs = [fm attributesOfItemAtPath:filename error:nil];
+ if (!fileAttrs)
+ return NO; // Error accessing the file means 'no'.
+ NSString *fileType = [fileAttrs fileType];
+ bool isDir = [fileType isEqualToString:NSFileTypeDirectory];
+ if (isDir) {
if ([mSavePanel treatsFilePackagesAsDirectories] == NO) {
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
return YES;
@@ -308,26 +329,35 @@ QT_USE_NAMESPACE
}
QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename);
- QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
- QString path = info.absolutePath();
- QString name = info.fileName();
- if (path != *mLastFilterCheckPath){
- *mLastFilterCheckPath = path;
- *mQDirFilterEntryList = info.dir().entryList(*mQDirFilter);
+ // No filter means accept everything
+ bool nameMatches = mSelectedNameFilter->isEmpty();
+ // Check if the current file name filter accepts the file:
+ for (int i = 0; !nameMatches && i < mSelectedNameFilter->size(); ++i) {
+ if (QDir::match(mSelectedNameFilter->at(i), qtFileName))
+ nameMatches = true;
}
- // Check if the QDir filter accepts the file:
- if (!mQDirFilterEntryList->contains(name))
+ if (!nameMatches)
return NO;
- // No filter means accept everything
- if (mSelectedNameFilter->isEmpty())
- return YES;
- // Check if the current file name filter accepts the file:
- for (int i=0; i<mSelectedNameFilter->size(); ++i) {
- if (QDir::match(mSelectedNameFilter->at(i), name))
- return YES;
+ QDir::Filters filter = *mQDirFilter;
+ if ((!(filter & (QDir::Dirs | QDir::AllDirs)) && isDir)
+ || (!(filter & QDir::Files) && [fileType isEqualToString:NSFileTypeRegular])
+ || ((filter & QDir::NoSymLinks) && [fileType isEqualToString:NSFileTypeSymbolicLink]))
+ return NO;
+
+ bool filterPermissions = ((filter & QDir::PermissionMask)
+ && (filter & QDir::PermissionMask) != QDir::PermissionMask);
+ if (filterPermissions) {
+ if ((!(filter & QDir::Readable) && [fm isReadableFileAtPath:filename])
+ || (!(filter & QDir::Writable) && [fm isWritableFileAtPath:filename])
+ || (!(filter & QDir::Executable) && [fm isExecutableFileAtPath:filename]))
+ return NO;
}
- return NO;
+ if (!(filter & QDir::Hidden)
+ && (qtFileName.startsWith(QLatin1Char('.')) || [self isHiddenFile:filename isDir:isDir]))
+ return NO;
+
+ return YES;
}
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag