From 62751db0d718a184cf42919ebdb200dd67a9f415 Mon Sep 17 00:00:00 2001 From: Sewon Ahn <129852908+lrycro@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:07:13 +0900 Subject: [PATCH] Merge pull request #30005 from lrycro:fix/glob-readdir-leak core: fix memory leak in glob()'s readdir() on WinRT/_WIN32_WCE - #30005 ## Problem Fixes #30004 In `modules/core/src/glob.cpp`, the WinRT/`_WIN32_WCE` implementation of `readdir()` allocates a new buffer for `dir->ent.d_name` on every call and overwrites the previous pointer without freeing it: ```cpp char* aname = new char[asize+1]; ... dir->ent.d_name = aname; ``` `cv::glob()` calls `readdir()` once per directory entry, so every call except the last leaks its allocation. Additionally, the `DIR` destructor that releases `d_name` was gated by `#ifdef WINRT` only, so `_WIN32_WCE` builds leaked every allocation, including the last one. ## Fix - Free the previous `dir->ent.d_name` before overwriting it in `readdir()`, matching how `~DIR()` already frees it on WinRT. - Extend the `DIR` destructor guard from `#ifdef WINRT` to `#if defined(WINRT) || defined(_WIN32_WCE)` so the final buffer is also released under `_WIN32_WCE`. ## Checklist - [x] I agree to contribute to the project under the Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on code under GPL or another license incompatible with OpenCV. - [x] The PR is proposed to the proper branch (`4.x`). - [x] There is a reference to the original bug report and related work. - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable. - [x] The feature is well documented and sample code can be built with the project CMake. Thanks for reviewing. --- modules/core/src/glob.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/core/src/glob.cpp b/modules/core/src/glob.cpp index 03638d49b1..fc83d64484 100644 --- a/modules/core/src/glob.cpp +++ b/modules/core/src/glob.cpp @@ -66,7 +66,7 @@ namespace #endif HANDLE handle; dirent ent; -#ifdef WINRT +#if defined(WINRT) || defined(_WIN32_WCE) DIR() { } ~DIR() { @@ -113,6 +113,7 @@ namespace char* aname = new char[asize+1]; aname[asize] = 0; wcstombs(aname, dir->data.cFileName, asize); + delete[] dir->ent.d_name; dir->ent.d_name = aname; #else if (dir->ent.d_name != 0)