diff options
author | Gabriel de Dietrich <gabriel.dedietrich@digia.com> | 2013-11-06 13:09:50 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-08 10:35:38 (GMT) |
commit | 07ecdc01a2b369fe330d723af1a00845c0932834 (patch) | |
tree | 9e71b6d47b0a1fa44bb6d92b94ba0b4272a684e6 /src | |
parent | 512a1ce0698d370c313bb561bbf078935fa0342e (diff) | |
download | Qt-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.mm | 66 |
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 |