← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/bug-1023862 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-1023862 into lp:zorba.

Requested reviews:
  Dennis Knochenwefel (dennis-knochenwefel)
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1023862 in Zorba: "file:list($path, true()) can produce infinite loops on some filesystems"
  https://bugs.launchpad.net/zorba/+bug/1023862

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1023862/+merge/114881

Added case for DT_UNKNOWN.
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-1023862/+merge/114881
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/util/fs_util.cpp'
--- src/util/fs_util.cpp	2012-07-12 17:29:55 +0000
+++ src/util/fs_util.cpp	2012-07-13 14:46:21 +0000
@@ -53,6 +53,16 @@
 
 ////////// helper functions ///////////////////////////////////////////////////
 
+#ifndef WIN32
+inline bool is_dots( char const *s ) {
+  return s[0] == '.' && (!s[1] || (s[1] == '.' && !s[2]));
+}
+#else
+inline bool is_dots( LPCWSTR s ) {
+  return s[0] == TEXT('.') && (!s[1] || (s[1] == TEXT('.') && !s[2]));
+}
+#endif /* WIN32 */
+
 inline void replace_foreign( zstring *path ) {
 #ifdef WIN32
   ascii::replace_all( *path, '/', '\\' );
@@ -323,9 +333,8 @@
       switch ( ent_->d_type ) {
         case DT_DIR: {
           char const *const name = ent_->d_name;
-          // skip "." and ".." entries
-          if ( name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2])) )
-            continue;
+          if ( is_dots( name ) )
+            continue;                   // skip "." and ".." entries
           ent_type_ = directory;
           break;
         }
@@ -335,6 +344,21 @@
         case DT_REG:
           ent_type_ = file;
           break;
+        case DT_UNKNOWN: {
+          //
+          // The d_type member is not supported by all filesystems. If it's
+          // not, it will be set to DT_UNKNOWN.  Hence, we're forced to do an
+          // explicit stat() to determine the entry type.
+          //
+          // This check fixes bug #1023862.
+          //
+          zstring ent_path( dir_path_ );
+          fs::append( ent_path, static_cast<char const*>( ent_->d_name ) );
+          ent_type_ = get_type( ent_path );
+          if ( ent_type_ == directory && is_dots( ent_->d_name ) )
+            continue;                   // skip "." and ".." entries
+          break;
+        }
         default:
           ent_type_ = other;
       }
@@ -352,11 +376,8 @@
         }
 
       LPCWSTR const wname = ent_data_.cFileName;
-      // skip "." and ".." entries
-      if ( wname[0] == TEXT('.') &&
-         (!wname[1] || wname[1] == TEXT('.') && !wname[2]) )
-        continue;
-
+      if ( is_dots( wname ) )
+        continue;                       // skip "." and ".." entries
       win32::to_char( wname, ent_name_ );
       ent_type_ = win32::map_type( ent_data_.dwFileAttributes );
       return true;


Follow ups