Commit cfadf08a6c06ce319f6144e724f45e4923e72778

  • avatar
  • Marius Storm-Olsen <marius @trol…ech.com>
  • Wed Jul 01 09:51:13 GMT 2009
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>
src/corelib/kernel/qcoreapplication.cpp
(2 / 7)
  
17411741 if (!d->cachedApplicationFilePath.isNull())
17421742 return d->cachedApplicationFilePath;
17431743
1744#if defined( Q_WS_WIN )
1745 wchar_t module_name[MAX_PATH];
1746 GetModuleFileName(0, module_name, MAX_PATH);
1747 module_name[MAX_PATH] = 0;
1748 QFileInfo filePath = QString::fromWCharArray(module_name);
1749
1750 d->cachedApplicationFilePath = filePath.filePath();
1744#if defined(Q_WS_WIN)
1745 d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
17511746 return d->cachedApplicationFilePath;
17521747#elif defined(Q_WS_MAC)
17531748 QString qAppFileName_str = qAppFileName();
src/corelib/kernel/qcoreapplication_win.cpp
(37 / 3)
  
7676
7777Q_CORE_EXPORT QString qAppFileName() // get application file name
7878{
79 wchar_t buffer[MAX_PATH];
80 GetModuleFileName(0, buffer, MAX_PATH);
81 return QString::fromWCharArray(buffer);
79 // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths
80 // up to, and including MAX_PATH size perfectly fine with string termination, as well
81 // as easily detect if the file path is indeed larger than MAX_PATH, in which case we
82 // need to use the heap instead. This is a work-around, since contrary to what the
83 // MSDN documentation states, GetModuleFileName sometimes doesn't set the
84 // ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if
85 // GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH.
86 // GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal
87 // file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use
88 // heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok).
89 wchar_t buffer[MAX_PATH + 2];
90 DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1);
91 buffer[MAX_PATH + 1] = 0;
92
93 if (v == 0)
94 return QString();
95 else if (v <= MAX_PATH)
96 return QString::fromWCharArray(buffer);
97
98 // MAX_PATH sized buffer wasn't large enough to contain the full path, use heap
99 wchar_t *b = 0;
100 int i = 1;
101 size_t size;
102 do {
103 ++i;
104 size = MAX_PATH * i;
105 b = reinterpret_cast<wchar_t *>(realloc(b, (size + 1) * sizeof(wchar_t)));
106 if (b)
107 v = GetModuleFileName(NULL, b, size);
108 } while (b && v == size);
109
110 if (b)
111 *(b + size) = 0;
112 QString res = QString::fromWCharArray(b);
113 free(b);
114
115 return res;
82116}
83117
84118void set_winapp_name()

Comments

Add a new comment:

Login or create an account to post a comment

Add your comment