diff --git a/QuickLook.Native/QuickLook.Native32/DOpus.cpp b/QuickLook.Native/QuickLook.Native32/DOpus.cpp index eb1355e61..a31fafe37 100644 --- a/QuickLook.Native/QuickLook.Native32/DOpus.cpp +++ b/QuickLook.Native/QuickLook.Native32/DOpus.cpp @@ -26,11 +26,12 @@ #define DOPUS_CLASS L"DOpus.ParentWindow" #define DOPUS_NAME L"Directory Opus" #define MSGWINDOW_CLASS L"QuickLook.Native.DOpus.MsgWindow" +#define MAX_BUFFER_SIZE (10 * 1024 * 1024) // 10MB limit for IPC data HWND hMsgWnd; HANDLE hGetResultEvent; -PCHAR pXmlBuffer; +PCHAR pXmlBuffer = nullptr; void DOpus::GetSelected(PWCHAR buffer) { @@ -72,9 +73,12 @@ void DOpus::GetSelected(PWCHAR buffer) WaitForSingleObject(hGetResultEvent, 2000); - ParseXmlBuffer(buffer); - - delete[] pXmlBuffer; + if (pXmlBuffer != nullptr) + { + ParseXmlBuffer(buffer); + delete[] pXmlBuffer; + pXmlBuffer = nullptr; + } } void DOpus::ParseXmlBuffer(PWCHAR buffer) @@ -88,6 +92,9 @@ void DOpus::ParseXmlBuffer(PWCHAR buffer) * ... */ + if (pXmlBuffer == nullptr) + return; + using namespace rapidxml; xml_document<> doc; @@ -130,8 +137,21 @@ LRESULT CALLBACK DOpus::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_COPYDATA: { auto cds = reinterpret_cast(lParam); + // Validate COPYDATASTRUCT and enforce reasonable size limit (10MB) + if (cds == nullptr || cds->lpData == nullptr || cds->cbData == 0 || cds->cbData > MAX_BUFFER_SIZE) + { + return 0; + } + auto buf = static_cast(cds->lpData); + // Clean up any previous buffer before allocating a new one + if (pXmlBuffer != nullptr) + { + delete[] pXmlBuffer; + pXmlBuffer = nullptr; + } + pXmlBuffer = new CHAR[cds->cbData + 1]{'\0'}; memcpy(pXmlBuffer, buf, cds->cbData); diff --git a/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp b/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp index 16ce94a71..0557ede33 100644 --- a/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp +++ b/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp @@ -46,6 +46,10 @@ void MultiCommander::GetSelected(PWCHAR buffer) return; } + if (pCurrentItemPath == nullptr) { + return; + } + auto path = reinterpret_cast(pCurrentItemPath); wcscpy_s(buffer, wcslen(path) + 1, path); @@ -84,8 +88,16 @@ LRESULT CALLBACK MultiCommander::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wPar case WM_COPYDATA: { delete[] pCurrentItemPath; + pCurrentItemPath = nullptr; auto cds = reinterpret_cast(lParam); + // Validate COPYDATASTRUCT and enforce reasonable size limit (10MB) + if (cds == nullptr || cds->lpData == nullptr || cds->cbData == 0 || cds->cbData > MAX_BUFFER_SIZE) + { + SetEvent(hGetResultEvent); + return 0; + } + auto buf = static_cast(cds->lpData); pCurrentItemPath = new CHAR[cds->cbData + 1]{ '\0' }; diff --git a/QuickLook.Native/QuickLook.Native32/MultiCommander.h b/QuickLook.Native/QuickLook.Native32/MultiCommander.h index 5279a3129..d6cdda128 100644 --- a/QuickLook.Native/QuickLook.Native32/MultiCommander.h +++ b/QuickLook.Native/QuickLook.Native32/MultiCommander.h @@ -19,6 +19,7 @@ #define MULTICMD_CPF_GETCURITEMFULL 0x00000010L // Get full path of current item (file or folder) in focus #define MULTICMD_CPF_SOURCE 0x00000400L // Go to the new path in the source panel side +#define MAX_BUFFER_SIZE (10 * 1024 * 1024) // 10MB limit for IPC data #define MULTICMD_CLASS L"MultiCommander MainWnd" #define MULTICMD_MSGWINDOW_CLASS L"QuickLook.Native.MultiCmd.MsgWindow" diff --git a/_codeql_detected_source_root b/_codeql_detected_source_root new file mode 120000 index 000000000..945c9b46d --- /dev/null +++ b/_codeql_detected_source_root @@ -0,0 +1 @@ +. \ No newline at end of file