/** * Returns a list of lines matching the specified pattern in all the files found * in the specified directory, each entry in the list contains the relative path * of the file and the number of the line where the pattern was found, as well * as the string around the pattern in that line. * * @param string $directory Directory where the scanner is located at the moment. * @param string $pattern Text that will be searched inside each file. * @return array Associative list with the file path and line number of the match. */ public function grep_pattern($directory = '', $pattern = '') { $dir_tree = $this->get_directory_tree($directory); $pattern = '/.*' . str_replace('/', '\\/', $pattern) . '.*/'; $results = array(); if (class_exists('SplFileObject') && class_exists('RegexIterator') && SucuriScan::is_valid_pattern($pattern)) { foreach ($dir_tree as $file_path) { try { $fobject = new SplFileObject($file_path); $fstream = new RegexIterator($fobject, $pattern, RegexIterator::MATCH); foreach ($fstream as $key => $ltext) { $lnumber = $key + 1; $ltext = str_replace("\n", '', $ltext); $fpath = str_replace($directory, '', $file_path); $loutput = sprintf('%s:%d:%s', $fpath, $lnumber, $ltext); $results[] = array('file_path' => $file_path, 'relative_path' => $fpath, 'line_number' => $lnumber, 'line_text' => $ltext, 'output' => $loutput); } } catch (RuntimeException $exception) { SucuriScanEvent::report_exception($exception); } } } return $results; }
/** * Retrieve a list with all the files contained in the main and subdirectories * of the folder specified. Some folders and files will be ignored depending * on some rules defined by the developer. * * @link http://www.php.net/manual/en/class.recursivedirectoryiterator.php * @see RecursiveDirectoryIterator extends FilesystemIterator * @see FilesystemIterator extends DirectoryIterator * @see DirectoryIterator extends SplFileInfo * @see SplFileInfo * * @param string $directory Parent directory where the filesystem scan will start. * @return array List of files in the main and subdirectories of the folder specified. */ private function get_directory_tree_with_spl($directory = '') { $files = array(); $filepath = @realpath($directory); $objects = array(); // Exception for directory name must not be empty. if ($filepath === false) { return $files; } if (!class_exists('FilesystemIterator')) { $this->scan_interface = 'opendir'; SucuriScanOption::update_option(':scan_interface', $this->scan_interface); $alternative_tree = $this->get_directory_tree($directory); return $alternative_tree; } try { if ($this->run_recursively) { $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS; $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($filepath, $flags), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD); } else { $objects = new DirectoryIterator($filepath); } } catch (RuntimeException $exception) { SucuriScanEvent::report_exception($exception); } foreach ($objects as $filepath => $fileinfo) { $filename = $fileinfo->getFilename(); if ($this->ignore_folderpath(null, $filename) || $this->skip_directories === true && $fileinfo->isDir()) { continue; } if ($this->run_recursively) { $directory = dirname($filepath); } else { $directory = $fileinfo->getPath(); $filepath = $directory . '/' . $filename; } if ($this->ignore_folderpath($directory, $filename) || $this->ignore_filepath($filename)) { continue; } $files[] = $filepath; } return $files; }