From 3181f1988d199f6aee23ebdf6146517640f7549e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 27 Sep 2023 15:33:32 +0200 Subject: [PATCH] Fix using *.* in wxDir under MSW Using "*.*" as a wildcard is supposed to match everything under MSW, but ever since the changes of 4daceaacbd (Check that files returned from wxDir::FindXXX() match the filter., 2013-04-08, see #3432) it only matched the files with extension because we double-checked the match returned by the native MSW function (which does handle "*.*" correctly) using our own wxString::Matches() which doesn't handle it specially. Fix this by skipping the call to Matches() when "*.*" is used: we know that this wildcard matches everything, so rechecking the match would be useless at best, even if it were not actively harmful. And also skip this call for "*" because calling Matches("*") always succeeds anyhow. This also fixes the same bug in wxFind{First,Next}File() and any other code using them such as wx{File,Dir}Ctrl. Closes #23905. --- src/msw/dir.cpp | 8 +++++++- tests/file/dir.cpp | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/msw/dir.cpp b/src/msw/dir.cpp index 5b05d23d48..691f732937 100644 --- a/src/msw/dir.cpp +++ b/src/msw/dir.cpp @@ -86,7 +86,13 @@ CheckFoundMatch(const FIND_STRUCT* finddata, const wxString& filter) // However if the filter contains only special characters (which is a // common case), we can skip the case conversion. if ( filter.find_first_not_of(wxS("*?.")) == wxString::npos ) - return fn.Matches(filter); + { + // And maybe even skip the check entirely if we have a filter that we + // know matches everything. This is more than just an optimization, as + // "*.*" it wouldn't match the files without extension according to + // wxString::Matches(), but it should. + return filter == wxS("*.*") || filter == wxS("*") || fn.Matches(filter); + } return fn.MakeUpper().Matches(filter.Upper()); } diff --git a/tests/file/dir.cpp b/tests/file/dir.cpp index ae5b81c5d5..5d11f80a52 100644 --- a/tests/file/dir.cpp +++ b/tests/file/dir.cpp @@ -20,6 +20,16 @@ #define DIRTEST_FOLDER wxString("dirTest_folder") #define SEP wxFileName::GetPathSeparator() +// We can't use wxFileSelectorDefaultWildcardStr from wxCore here, so define +// our own. +const char WILDCARD_ALL[] = +#if defined(__WXMSW__) +"*.*" +#else // Unix/Mac +"*" +#endif +; + // ---------------------------------------------------------------------------- // test fixture // ---------------------------------------------------------------------------- @@ -145,6 +155,9 @@ TEST_CASE_METHOD(DirTestCase, "Dir::Traverse", "[dir]") wxArrayString files; CHECK( wxDir::GetAllFiles(DIRTEST_FOLDER, &files) == 4 ); + // enum all files using an explicit wildcard + CHECK(wxDir::GetAllFiles(DIRTEST_FOLDER, &files, WILDCARD_ALL) == 4); + // enum all files according to the filter CHECK( wxDir::GetAllFiles(DIRTEST_FOLDER, &files, "*.foo") == 1 );