diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2015-03-11 14:38:59 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2019-05-21 13:59:34 +0200 |
commit | bd55a9d91227d1ac38f51b21ca23dec7fa5e82af (patch) | |
tree | cc2855e2078f4550025a82eff2758d010c3c32e5 /src/corelib/io/qfilesystemengine_unix.cpp | |
parent | bba44746f9f2cfca785a309deb056033ae0bea6e (diff) |
Fix canonicalFilePath() for files with trailing slashes
Such files do not exist (as per QFileInfo::exists), but on some
platforms that rely on realpath(), QFileInfo::canonicalFilePath did
not return the empty string.
Use the same logic on macOS as we already did on Android, and include
a test case. Remove the unnecessary dynamic memory allocation and
use a stack-allocated array instead, unless we use modern POSIX in
which case realpath() will alloc the memory for the result for us.
Change-Id: Ide987c68ebf00cbb7b1a66c2e9245a12c7807128
Fixes: QTBUG-44242
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/io/qfilesystemengine_unix.cpp')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5bab897d43..b78e037865 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -695,52 +695,36 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, Q_UNUSED(data); return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); #else - char *ret = 0; -# if defined(Q_OS_DARWIN) - ret = (char*)malloc(PATH_MAX + 1); - if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } -# elif defined(Q_OS_ANDROID) - // On some Android versions, realpath() will return a path even if it does not exist - // To work around this, we check existence in advance. + char stack_result[PATH_MAX+1]; + char *resolved_name = nullptr; +# if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID) + // On some Android and macOS versions, realpath() will return a path even if + // it does not exist. To work around this, we check existence in advance. if (!data.hasFlags(QFileSystemMetaData::ExistsAttribute)) fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); if (!data.exists()) { - ret = 0; errno = ENOENT; } else { - ret = (char*)malloc(PATH_MAX + 1); - if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } + resolved_name = stack_result; } - + if (resolved_name && realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr) + resolved_name = nullptr; # else -# if _POSIX_VERSION >= 200801L - ret = realpath(entry.nativeFilePath().constData(), (char*)0); +# if _POSIX_VERSION >= 200801L // ask realpath to allocate memory + resolved_name = realpath(entry.nativeFilePath().constData(), nullptr); # else - ret = (char*)malloc(PATH_MAX + 1); - if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) { - const int savedErrno = errno; // errno is checked below, and free() might change it - free(ret); - errno = savedErrno; - ret = 0; - } + resolved_name = stack_result; + if (realpath(entry.nativeFilePath().constData(), resolved_name) == nullptr) + resolved_name = nullptr; # endif # endif - if (ret) { + if (resolved_name) { data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; data.entryFlags |= QFileSystemMetaData::ExistsAttribute; - QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret)); - free(ret); + QString canonicalPath = QDir::cleanPath(QFile::decodeName(resolved_name)); + if (resolved_name != stack_result) + free(resolved_name); return QFileSystemEntry(canonicalPath); } else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; |