diff --git a/xpcom/base/nsWindowsHelpers.h b/xpcom/base/nsWindowsHelpers.h index 552e74f4740..2cbb9cf24a5 100644 --- a/xpcom/base/nsWindowsHelpers.h +++ b/xpcom/base/nsWindowsHelpers.h @@ -10,6 +10,7 @@ #include #include "nsAutoRef.h" #include "nscore.h" +#include "mozilla/Assertions.h" // ---------------------------------------------------------------------------- // Critical Section helper class @@ -223,30 +224,57 @@ typedef nsAutoRef nsAutoDevMode; namespace { +// Construct a path "\". return false if the output buffer +// is too small. +// Note: If the system path cannot be found, or doesn't fit in the output buffer +// with the module name, we will just ignore the system path and output the +// module name alone; +// this may mean using a normal search path wherever the output is used. +bool inline +ConstructSystem32Path(LPCWSTR aModule, WCHAR* aSystemPath, UINT aSize) +{ + MOZ_ASSERT(aSystemPath); + + size_t fileLen = wcslen(aModule); + if (fileLen >= aSize) { + // The module name alone cannot even fit! + return false; + } + + size_t systemDirLen = GetSystemDirectoryW(aSystemPath, aSize); + + if (systemDirLen) { + if (systemDirLen < aSize - fileLen) { + // Make the system directory path terminate with a slash. + if (aSystemPath[systemDirLen - 1] != L'\\') { + if (systemDirLen + 1 < aSize - fileLen) { + aSystemPath[systemDirLen] = L'\\'; + ++systemDirLen; + // No need to re-nullptr terminate. + } else { + // Couldn't fit the system path with added slash. + systemDirLen = 0; + } + } + } else { + // Couldn't fit the system path. + systemDirLen = 0; + } + } + + MOZ_ASSERT(systemDirLen + fileLen < aSize); + + wcsncpy(aSystemPath + systemDirLen, aModule, fileLen); + aSystemPath[systemDirLen + fileLen] = L'\0'; + return true; +} + HMODULE inline LoadLibrarySystem32(LPCWSTR aModule) { - WCHAR systemPath[MAX_PATH + 1] = { L'\0' }; - - // If GetSystemPath fails we accept that we'll load the DLLs from the - // normal search path. - GetSystemDirectoryW(systemPath, MAX_PATH + 1); - size_t systemDirLen = wcslen(systemPath); - - // Make the system directory path terminate with a slash - if (systemDirLen && systemPath[systemDirLen - 1] != L'\\') { - systemPath[systemDirLen] = L'\\'; - ++systemDirLen; - // No need to re-nullptr terminate - } - - size_t fileLen = wcslen(aModule); - wcsncpy(systemPath + systemDirLen, aModule, - MAX_PATH - systemDirLen); - if (systemDirLen + fileLen <= MAX_PATH) { - systemPath[systemDirLen + fileLen] = L'\0'; - } else { - systemPath[MAX_PATH] = L'\0'; + WCHAR systemPath[MAX_PATH + 1]; + if (!ConstructSystem32Path(aModule, systemPath, MAX_PATH + 1)) { + return NULL; } return LoadLibraryW(systemPath); }