]> git.saurik.com Git - wxWidgets.git/commitdiff
Check that files returned from wxDir::FindXXX() match the filter.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 8 Apr 2013 10:03:48 +0000 (10:03 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 8 Apr 2013 10:03:48 +0000 (10:03 +0000)
Native Windows functions used by wxDir check the filter against both the short
and the long name resulting in unexpected results, e.g. searching for
"foo.baz" would find "foo.bazaar".

Fix this by explicitly rechecking that we have a valid match ourselves.

Closes #3432.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73790 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
src/msw/dir.cpp

index 7789ce6bd9b45d5fa380eb66ee580362dc3317cf..0e17ef80d477145b31891e10f4c1bfc85f2b33c8 100644 (file)
@@ -658,6 +658,7 @@ wxMSW:
 - Improve wxCURSOR_RIGHT_ARROW appearance (DoltAlya).
 - Generate menu highlight events for popup menus in wxDialog (Sam Partington).
 - Return more native shell icons from wxArtProvider (Markus Juergens).
+- Fix filter checks in wxDir::FindFirst/Next() (Catalin Raceanu).
 
 wxOSX/Cocoa:
 
index 2eea8fe7ffc04f4444aa45f630d2d8f98ef89f0e..55f855cf6f9ffe9ecbd48b917a64f6e2b829b98b 100644 (file)
@@ -64,20 +64,60 @@ inline void FreeFindData(FIND_DATA fd)
     }
 }
 
-inline FIND_DATA FindFirst(const wxString& spec,
-                           FIND_STRUCT *finddata)
+const wxChar *GetNameFromFindData(const FIND_STRUCT *finddata)
 {
-    return ::FindFirstFile(spec.t_str(), finddata);
+    return finddata->cFileName;
 }
 
-inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)
+// Helper function checking that the contents of the given FIND_STRUCT really
+// match our filter. We need to do it ourselves as native Windows functions
+// apply the filter to both the long and the short names of the file, so
+// something like "*.bar" matches "foo.bar.baz" too and not only "foo.bar", so
+// we have to double check that we have a real match.
+inline bool
+CheckFoundMatch(const FIND_STRUCT* finddata, const wxString& filter)
 {
-    return ::FindNextFile(fd, finddata) != 0;
+    return filter.empty() ||
+                wxString(GetNameFromFindData(finddata)).Matches(filter);
 }
 
-const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
+inline bool
+FindNext(FIND_DATA fd, const wxString& filter, FIND_STRUCT *finddata)
 {
-    return finddata->cFileName;
+    for ( ;; )
+    {
+        if ( !::FindNextFile(fd, finddata) )
+            return false;
+
+        // If we did find something, check that it really matches.
+        if ( CheckFoundMatch(finddata, filter) )
+            return true;
+    }
+}
+
+inline FIND_DATA
+FindFirst(const wxString& spec,
+          const wxString& filter,
+          FIND_STRUCT *finddata)
+{
+    FIND_DATA fd = ::FindFirstFile(spec.t_str(), finddata);
+
+    // As in FindNext() above, we need to check that the file name we found
+    // really matches our filter and look for the next match if it doesn't.
+    if ( IsFindDataOk(fd) && !CheckFoundMatch(finddata, filter) )
+    {
+        if ( !FindNext(fd, filter, finddata) )
+        {
+            // As we return the invalid handle from here to indicate that we
+            // didn't find anything, close the one we initially received
+            // ourselves.
+            FreeFindData(fd);
+
+            return INVALID_HANDLE_VALUE;
+        }
+    }
+
+    return fd;
 }
 
 inline FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
@@ -196,7 +236,7 @@ bool wxDirData::Read(wxString *filename)
         else
             filespec += m_filespec;
 
-        m_finddata = FindFirst(filespec, PTR_TO_FINDDATA);
+        m_finddata = FindFirst(filespec, m_filespec, PTR_TO_FINDDATA);
 
         first = true;
     }
@@ -228,7 +268,7 @@ bool wxDirData::Read(wxString *filename)
         }
         else
         {
-            if ( !FindNext(m_finddata, PTR_TO_FINDDATA) )
+            if ( !FindNext(m_finddata, m_filespec, PTR_TO_FINDDATA) )
             {
 #ifdef __WIN32__
                 DWORD err = ::GetLastError();
@@ -400,7 +440,7 @@ wxGetDirectoryTimes(const wxString& dirname,
 #endif
 
     FIND_STRUCT fs;
-    FIND_DATA fd = FindFirst(dirname, &fs);
+    FIND_DATA fd = FindFirst(dirname, wxEmptyString, &fs);
     if ( !IsFindDataOk(fd) )
     {
         return false;