summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2011-08-05 08:57:19 (GMT)
committerJoão Abecasis <joao.abecasis@nokia.com>2011-08-17 15:52:21 (GMT)
commitd71d3b1ce31ffc585258330d825ff8ea535254ef (patch)
tree2058c6a30106731da937b3b253d30db1a73c7b9b /src/corelib
parent63bb67d3107b03f399cddf4c9cca9c7eb347b62d (diff)
downloadQt-d71d3b1ce31ffc585258330d825ff8ea535254ef.zip
Qt-d71d3b1ce31ffc585258330d825ff8ea535254ef.tar.gz
Qt-d71d3b1ce31ffc585258330d825ff8ea535254ef.tar.bz2
Use QStringBuilder when copying template for modification
This avoids modifying the original string in the case where a placeholder marker is not found. By marking the variable const we further avoid checks on the reference count and detaches, also allowing us to safely reuse it later in the function. The new approach also fixes an issue where suffix wasn't empty, but the toLocal8Bit conversion would be. This resulted in a buffer overflow inside createFileFromTemplate. Reviewed-by: Shane Kearns
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qtemporaryfile.cpp62
1 files changed, 47 insertions, 15 deletions
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 497faad..b079d3e 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -45,6 +45,7 @@
#include "qplatformdefs.h"
#include "qabstractfileengine.h"
+#include "qstringbuilder.h"
#include "private/qfile_p.h"
#include "private/qabstractfileengine_p.h"
#include "private/qfsfileengine_p.h"
@@ -60,6 +61,38 @@
QT_BEGIN_NAMESPACE
+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.
@@ -258,7 +291,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
if (!filePathIsTemplate)
return QFSFileEngine::open(openMode);
- QString qfilename = d->fileEntry.filePath();
+ const QString qfilename = d->fileEntry.filePath();
// Find placeholder string.
uint phPos = qfilename.length();
@@ -281,22 +314,22 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
phLength = 0;
}
- QStringRef prefix, suffix;
+ QByteArray filename;
+
if (phLength < 6) {
- qfilename += QLatin1Char('.');
- prefix = QStringRef(&qfilename);
+ filename = qfilename.toLocal8Bit();
+
+ phPos = filename.length() + 1; // Account for added dot in prefix
phLength = 6;
+ filename = filename % '.' % Placeholder(phLength);
} else {
- prefix = qfilename.leftRef(phPos);
- suffix = qfilename.midRef(phPos + phLength);
- }
+ QByteArray prefix, suffix;
+ prefix = qfilename.leftRef(phPos).toLocal8Bit();
+ suffix = qfilename.midRef(phPos + phLength).toLocal8Bit();
- QByteArray filename = prefix.toLocal8Bit();
- phPos = filename.length();
- if (suffix.isEmpty())
- filename.resize(phPos + phLength);
- else
- filename.insert(phPos + phLength, suffix.toLocal8Bit());
+ phPos = prefix.length();
+ filename = prefix % Placeholder(phLength) % suffix;
+ }
int fd = createFileFromTemplate(filename, phPos, phLength);
@@ -323,14 +356,13 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
if (fd == -1)
return false;
- QString template_ = d->fileEntry.filePath();
d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length()));
if (QFSFileEngine::open(openMode)) {
filePathIsTemplate = false;
return true;
}
- d->fileEntry = QFileSystemEntry(template_, QFileSystemEntry::FromInternalPath());
+ d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
return false;
#endif
}