}
else {
require_once 'DB.php';
+ $dsn = CRM_Utils_SQL::autoSwitchDSN($dsn);
$db = DB::connect($dsn);
}
* @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 = [];
}
}
}
+ // 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;
}
}