Fix QTemporaryFile regressions and new found issues
With this change, the file template is always processed in original QString format. Trying to generate native paths before adding a missing placeholder mask could change the meaning of templates, such as "." and "..", which are now tested to mean "..XXXXXX" and "...XXXXXX", respectively. After ensuring the template includes a placeholder mask, the path is converted to a native *absolute* file path and the mask is sought for again. On Windows, native paths were already absolute. On Symbian, we'd need at least a clean path, as "." and ",," are not natively understood. There is a requirement that the placeholder mask /XXXXXX+/ makes it through this conversion unaltered, which relaxes prior requirements on *nix platforms. On Windows and Symbian the conversion is under Qt's control and not user-configurable. Reviewed-by: Shane Kearns (cherry picked from commit 401722ef9e6fe79bd41f9d5f79668f5c4997c8e6) Conflicts: tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp Change-Id: Iac823881c865adf0931dc4f429c6c1ef135eeb56 Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
This commit is contained in:
parent
c9fde0d590
commit
fd61059d35
@ -44,10 +44,10 @@
|
||||
#ifndef QT_NO_TEMPORARYFILE
|
||||
|
||||
#include "qplatformdefs.h"
|
||||
#include "qstringbuilder.h"
|
||||
#include "private/qfile_p.h"
|
||||
#include "private/qfsfileengine_p.h"
|
||||
#include "private/qsystemerror_p.h"
|
||||
#include "private/qfilesystemengine_p.h"
|
||||
|
||||
#if defined(Q_OS_SYMBIAN)
|
||||
#include "private/qcore_symbian_p.h"
|
||||
@ -102,38 +102,6 @@ typedef char Latin1Char;
|
||||
typedef int NativeFileHandle;
|
||||
#endif
|
||||
|
||||
struct Placeholder
|
||||
{
|
||||
Placeholder(int size)
|
||||
: size_(size)
|
||||
{
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
int size_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct QConcatenable<Placeholder>
|
||||
{
|
||||
typedef Placeholder type;
|
||||
typedef QByteArray ConvertTo;
|
||||
enum { ExactSize = true };
|
||||
static int size(const Placeholder &p) { return p.size(); }
|
||||
|
||||
template <class CharT>
|
||||
static inline void appendTo(const Placeholder &p, CharT *&out)
|
||||
{
|
||||
// Uninitialized
|
||||
out += p.size();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -366,43 +334,59 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
|
||||
if (!filePathIsTemplate)
|
||||
return QFSFileEngine::open(openMode);
|
||||
|
||||
const QFileSystemEntry::NativePath qfilename = d->fileEntry.nativeFilePath();
|
||||
QString qfilename = d->fileEntry.filePath();
|
||||
|
||||
// Find placeholder string.
|
||||
// Ensure there is a placeholder mask
|
||||
uint phPos = qfilename.length();
|
||||
uint phLength = 0;
|
||||
|
||||
while (phPos != 0) {
|
||||
--phPos;
|
||||
|
||||
if (qfilename[phPos] == Latin1Char('X')) {
|
||||
if (qfilename[phPos] == QLatin1Char('X')) {
|
||||
++phLength;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (phLength >= 6
|
||||
|| qfilename[phPos] ==
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
|
||||
'/'
|
||||
#else
|
||||
QLatin1Char('\\')
|
||||
#endif
|
||||
) {
|
||||
|| qfilename[phPos] == QLatin1Char('/')) {
|
||||
++phPos;
|
||||
break;
|
||||
}
|
||||
|
||||
// start over
|
||||
phLength = 0;
|
||||
}
|
||||
|
||||
QFileSystemEntry::NativePath filename;
|
||||
if (phLength < 6)
|
||||
qfilename.append(QLatin1String(".XXXXXX"));
|
||||
|
||||
if (phLength < 6) {
|
||||
phPos = qfilename.length() + 1; // Account for added dot in prefix
|
||||
phLength = 6;
|
||||
filename = qfilename % Latin1Char('.') % Placeholder(phLength);
|
||||
} else
|
||||
filename = qfilename;
|
||||
// "Nativify" :-)
|
||||
QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName(
|
||||
QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath()))
|
||||
.nativeFilePath();
|
||||
|
||||
// Find mask in native path
|
||||
phPos = filename.length();
|
||||
phLength = 0;
|
||||
while (phPos != 0) {
|
||||
--phPos;
|
||||
|
||||
if (filename[phPos] == Latin1Char('X')) {
|
||||
++phLength;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (phLength >= 6) {
|
||||
++phPos;
|
||||
break;
|
||||
}
|
||||
|
||||
// start over
|
||||
phLength = 0;
|
||||
}
|
||||
|
||||
Q_ASSERT(phLength >= 6);
|
||||
|
||||
QSystemError error;
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -647,6 +647,8 @@ void tst_QTemporaryFile::QTBUG_4796_data()
|
||||
QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8");
|
||||
|
||||
QTest::newRow("<empty>") << QString() << QString() << true;
|
||||
QTest::newRow(".") << QString(".") << QString() << true;
|
||||
QTest::newRow("..") << QString("..") << QString() << true;
|
||||
QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true;
|
||||
QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true;
|
||||
QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false;
|
||||
|
Loading…
Reference in New Issue
Block a user