summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMarius Storm-Olsen <marius@trolltech.com>2009-07-01 09:49:51 (GMT)
committerMarius Storm-Olsen <marius@trolltech.com>2009-07-01 09:51:13 (GMT)
commitcfadf08a6c06ce319f6144e724f45e4923e72778 (patch)
tree672f5e0515b2b0cf718aca773eb87f9f4f738f0e /src/corelib
parent5ae330b6546dabada53c394b53ce9513f552a8a5 (diff)
downloadQt-cfadf08a6c06ce319f6144e724f45e4923e72778.zip
Qt-cfadf08a6c06ce319f6144e724f45e4923e72778.tar.gz
Qt-cfadf08a6c06ce319f6144e724f45e4923e72778.tar.bz2
Handle application paths larger than MAX_PATH, and fix potential buffer overflow
These days we can easily get very long paths, so we should support application paths as long as needed. There was also a potention exploit in that if the path was MAX_PATH or larger, the string would not be \0 terminated (see MSDN docs for GetModuleFileName), and thus cause problems in QString::fromWCharArray(). Merge-request: 604 Reviewed-by: Marius Storm-Olsen <marius@trolltech.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp9
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp40
2 files changed, 39 insertions, 10 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index f0a3fec..e2708c3 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1741,13 +1741,8 @@ QString QCoreApplication::applicationFilePath()
if (!d->cachedApplicationFilePath.isNull())
return d->cachedApplicationFilePath;
-#if defined( Q_WS_WIN )
- wchar_t module_name[MAX_PATH];
- GetModuleFileName(0, module_name, MAX_PATH);
- module_name[MAX_PATH] = 0;
- QFileInfo filePath = QString::fromWCharArray(module_name);
-
- d->cachedApplicationFilePath = filePath.filePath();
+#if defined(Q_WS_WIN)
+ d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
return d->cachedApplicationFilePath;
#elif defined(Q_WS_MAC)
QString qAppFileName_str = qAppFileName();
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 657abd1..a71f284 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -76,9 +76,43 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho
Q_CORE_EXPORT QString qAppFileName() // get application file name
{
- wchar_t buffer[MAX_PATH];
- GetModuleFileName(0, buffer, MAX_PATH);
- return QString::fromWCharArray(buffer);
+ // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths
+ // up to, and including MAX_PATH size perfectly fine with string termination, as well
+ // as easily detect if the file path is indeed larger than MAX_PATH, in which case we
+ // need to use the heap instead. This is a work-around, since contrary to what the
+ // MSDN documentation states, GetModuleFileName sometimes doesn't set the
+ // ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if
+ // GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH.
+ // GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal
+ // file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use
+ // heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok).
+ wchar_t buffer[MAX_PATH + 2];
+ DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1);
+ buffer[MAX_PATH + 1] = 0;
+
+ if (v == 0)
+ return QString();
+ else if (v <= MAX_PATH)
+ return QString::fromWCharArray(buffer);
+
+ // MAX_PATH sized buffer wasn't large enough to contain the full path, use heap
+ wchar_t *b = 0;
+ int i = 1;
+ size_t size;
+ do {
+ ++i;
+ size = MAX_PATH * i;
+ b = reinterpret_cast<wchar_t *>(realloc(b, (size + 1) * sizeof(wchar_t)));
+ if (b)
+ v = GetModuleFileName(NULL, b, size);
+ } while (b && v == size);
+
+ if (b)
+ *(b + size) = 0;
+ QString res = QString::fromWCharArray(b);
+ free(b);
+
+ return res;
}
void set_winapp_name()