1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Limit taint file re-analysis

This commit is contained in:
Matthew Brown 2019-10-13 12:34:40 -04:00
parent cd8534fb6c
commit 3c00f3d029
2 changed files with 60 additions and 0 deletions

View File

@ -260,6 +260,13 @@ class Analyzer
while ($codebase->taint->hasNewSinksAndSources() && ++$i <= 4) {
$project_analyzer->progress->write("\n\n" . 'Found tainted inputs, reanalysing' . "\n\n");
$this->files_to_analyze = $codebase->taint->getFilesToAnalyze(
$codebase->file_reference_provider,
$codebase->file_storage_provider,
$codebase->classlike_storage_provider,
$codebase->config
);
$codebase->taint->clearNewSinksAndSources();
$this->doAnalysis($project_analyzer, $pool_size, true);

View File

@ -4,6 +4,9 @@ namespace Psalm\Internal\Codebase;
use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Taint\Sink;
use Psalm\Internal\Taint\Source;
use Psalm\Internal\Taint\Taintable;
@ -266,6 +269,10 @@ class Taint
public function hasNewSinksAndSources() : bool
{
if (!self::$archived_sources && !$this->new_sources) {
return false;
}
return $this->new_sinks || $this->new_sources;
}
@ -292,6 +299,52 @@ class Taint
}
}
/**
* @return array<string, string>
*/
public function getFilesToAnalyze(
FileReferenceProvider $reference_provider,
FileStorageProvider $file_storage_provider,
ClassLikeStorageProvider $classlike_storage_provider,
\Psalm\Config $config
) : array
{
$files = [];
foreach (array_merge(self::$archived_sinks, $this->new_sinks) as $new_sink) {
if ($new_sink && $new_sink->code_location) {
$files = array_merge(
$reference_provider->getFilesReferencingFile($new_sink->code_location->file_path),
$files
);
}
}
foreach (array_merge(self::$archived_sources, $this->new_sources) as $new_source) {
if ($new_source && $new_source->code_location) {
$classlikes = $file_storage_provider->get($new_source->code_location->file_path)->classlikes_in_file;
foreach ($classlikes as $classlike) {
$class_storage = $classlike_storage_provider->get($classlike);
if ($class_storage->location) {
$files[] = $class_storage->location->file_path;
}
}
}
}
$files = array_filter(
$files,
function($file) use ($config) {
return $config->isInProjectDirs($file);
}
);
$arr = array_values($files);
return array_combine($arr, $arr);
}
public function clearNewSinksAndSources() : void
{
self::$archived_sinks = array_merge(