diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2011-03-30 12:27:00 (GMT) |
---|---|---|
committer | João Abecasis <joao.abecasis@nokia.com> | 2011-04-04 11:22:56 (GMT) |
commit | c728783dc20cc2d4667affdefa19a4162a2ec9ef (patch) | |
tree | 0e61bdb7e464ba334e2879a6f210db0d4bd8489c /src/corelib/io | |
parent | 3d041873576e05bf19923f643878ac4d9ca33057 (diff) | |
download | Qt-c728783dc20cc2d4667affdefa19a4162a2ec9ef.zip Qt-c728783dc20cc2d4667affdefa19a4162a2ec9ef.tar.gz Qt-c728783dc20cc2d4667affdefa19a4162a2ec9ef.tar.bz2 |
QTemporaryFile: Locate placeholder before re-encoding
Previously, the placeholder was identified in unicode-based QString, and
the offset was assumed to be correct after conversion to the local 8-bit
encoding. This assumption is obviously wrong for variable-sized
encoding, such as utf-8.
With this change, the placeholder is still identified in the original
QString, but conversion to 8-bit encoding is done in a step-wise fashion
and offsets recomputed. This allows us to drop the intermediary argument
verification in _gettemp.
Task-number: QTBUG-4796
Reviewed-by: Robin Burchell
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qtemporaryfile.cpp | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 92065cb..34c01a6 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -95,31 +95,6 @@ QT_BEGIN_NAMESPACE * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -static int createFileFromTemplate(char *const path, - char *const placeholderStart, char *const placeholderEnd); - -static int _gettemp(char *path, int slen) -{ - char *trv, *suffp; - - for (trv = path; *trv; ++trv) - ; - trv -= slen; - suffp = trv; - --trv; - if (trv < path) { - errno = EINVAL; - return -1; - } - - while (trv >= path && *trv == 'X') - --trv; - - char *const placeholderStart = trv + 1; - char *const placeholderEnd = suffp; - - return createFileFromTemplate(path, placeholderStart, placeholderEnd); -} /*! \internal @@ -274,15 +249,49 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) return QFSFileEngine::open(openMode); QString qfilename = d->fileEntry.filePath(); - if(!qfilename.contains(QLatin1String("XXXXXX"))) - qfilename += QLatin1String(".XXXXXX"); - int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6); - QByteArray filename = qfilename.toLocal8Bit(); + // Find placeholder string. + size_t phPos = size_t(qfilename.length()); + size_t phLength = 0; + + while (phPos != 0) { + --phPos; + + if (qfilename[phPos] == QLatin1Char('X')) { + ++phLength; + continue; + } + + if (qfilename[phPos] == QLatin1Char('/') + || phLength >= 6) { + ++phPos; + break; + } + + phLength = 0; + } + + QStringRef prefix, suffix; + if (phLength < 6) { + qfilename += QLatin1Char('.'); + prefix = QStringRef(&qfilename); + phLength = 6; + } else { + prefix = qfilename.leftRef(phPos); + suffix = qfilename.midRef(phPos + phLength); + } + + QByteArray filename = prefix.toLocal8Bit(); + phPos = filename.length(); + if (suffix.isEmpty()) + filename.resize(phPos + phLength); + else + filename.insert(phPos + phLength, suffix.toLocal8Bit()); + char *path = filename.data(); #ifndef Q_OS_WIN - int fd = _gettemp(path, suffixLength); + int fd = createFileFromTemplate(path, path + phPos, path + phPos + phLength); if (fd != -1) { // First open the fd as an external file descriptor to // initialize the engine properly. @@ -302,7 +311,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); return false; #else - if (_gettemp(path, suffixLength) == -1) { + if (createFileFromTemplate(path, path + phPos, path + phPos + phLength) == -1) { return false; } |