Merge pull request #18819 from eileenmcnaughton/import
[civicrm-core.git] / CRM / Utils / File.php
index ff1bccb6bf59327a81bdd6e17203f0ac71323789..c196b3dd712697cfe368567e025b4f244a137be1 100644 (file)
@@ -325,6 +325,7 @@ class CRM_Utils_File {
     }
     else {
       require_once 'DB.php';
+      $dsn = CRM_Utils_SQL::autoSwitchDSN($dsn);
       $db = DB::connect($dsn);
     }
 
@@ -753,9 +754,16 @@ HTACCESS;
    * @return array(string)
    */
   public static function findFiles($dir, $pattern, $relative = FALSE) {
-    if (!is_dir($dir)) {
+    if (!is_dir($dir) || !is_readable($dir)) {
       return [];
     }
+    // Which dirs should we exclude from our searches?
+    // If not defined, we default to excluding any dirname that begins
+    // with a . which is the old behaviour and therefore excludes .git/
+    $excludeDirsPattern = defined('CIVICRM_EXCLUDE_DIRS_PATTERN')
+      ? constant('CIVICRM_EXCLUDE_DIRS_PATTERN')
+      : '@' . preg_quote(DIRECTORY_SEPARATOR) . '\.@';
+
     $dir = rtrim($dir, '/');
     $todos = [$dir];
     $result = [];
@@ -769,13 +777,21 @@ HTACCESS;
           }
         }
       }
+      // Find subdirs to recurse into.
       if ($dh = opendir($subdir)) {
         while (FALSE !== ($entry = readdir($dh))) {
           $path = $subdir . DIRECTORY_SEPARATOR . $entry;
-          if ($entry{0} == '.') {
-            // ignore
-          }
-          elseif (is_dir($path)) {
+          // Exclude . (self) and .. (parent) to avoid infinite loop.
+          // Exclude configured exclude dirs.
+          // Exclude dirs we can't read.
+          // Exclude anything that's not a dir.
+          if (
+            $entry !== '.'
+            && $entry !== '..'
+            && (empty($excludeDirsPattern) || !preg_match($excludeDirsPattern, $path))
+            && is_dir($path)
+            && is_readable($path)
+          ) {
             $todos[] = $path;
           }
         }