Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callmap is always non-empty #9405

Merged
merged 2 commits into from
Feb 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion dictionaries/InternalTaintSinkMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// This maps internal function names to sink types that we don’t want to end up there

/**
* @var array<string, list<list<TaintKind::*>>>
* @var non-empty-array<string, non-empty-list<list<TaintKind::*>>>
*/
return [
'exec' => [['shell']],
Expand Down
12 changes: 0 additions & 12 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@
<code>$args[0]</code>
<code>$args[0]</code>
<code>$args[1]</code>
<code>$callmap_callables[0]</code>
<code>$method_name</code>
</PossiblyUndefinedIntArrayOffset>
</file>
Expand Down Expand Up @@ -257,17 +256,6 @@
<code>$stub</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Codebase/InternalCallMapHandler.php">
<PossiblyUndefinedIntArrayOffset>
<code>$callables[0]</code>
<code>$callables[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Codebase/Methods.php">
<PossiblyUndefinedIntArrayOffset>
<code>$function_callables[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Codebase/Properties.php">
<PossiblyUndefinedIntArrayOffset>
<code>$property_name</code>
Expand Down
40 changes: 24 additions & 16 deletions src/Psalm/Internal/Codebase/InternalCallMapHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ class InternalCallMapHandler
private static ?int $loaded_php_minor_version = null;

/**
* @var array<lowercase-string, array<int|string,string>>|null
* @var non-empty-array<lowercase-string, array<int|string,string>>|null
*/
private static ?array $call_map = null;

/**
* @var array<list<TCallable>>|null
* @var array<string, non-empty-list<TCallable>>|null
*/
private static ?array $call_map_callables = [];

/**
* @var array<string, list<list<TaintKind::*>>>
* @var non-empty-array<string, non-empty-list<list<TaintKind::*>>>|null
*/
private static array $taint_sink_map = [];
private static ?array $taint_sink_map = null;

/**
* @param list<PhpParser\Node\Arg> $args
Expand Down Expand Up @@ -84,7 +84,7 @@ public static function getCallableFromCallMapById(
}

/**
* @param array<int, TCallable> $callables
* @param non-empty-list<TCallable> $callables
* @param list<PhpParser\Node\Arg> $args
*/
public static function getMatchingCallableFromCallMapOptions(
Expand Down Expand Up @@ -216,7 +216,7 @@ public static function getMatchingCallableFromCallMapOptions(
}

/**
* @return list<TCallable>|null
* @return non-empty-list<TCallable>|null
*/
public static function getCallablesFromCallMap(string $function_id): ?array
{
Expand Down Expand Up @@ -332,7 +332,9 @@ public static function getCallablesFromCallMap(string $function_id): ?array
/**
* Gets the method/function call map
*
* @return array<string, array<int|string, string>>
* @return non-empty-array<string, array<int|string, string>>
* @psalm-assert !null self::$taint_sink_map
* @psalm-assert !null self::$call_map
*/
public static function getCallMap(): array
{
Expand All @@ -353,26 +355,31 @@ public static function getCallMap(): array
return self::$call_map;
}

/** @var array<string, array<int|string, string>> */
$call_map = require(dirname(__DIR__, 4) . '/dictionaries/CallMap.php');
/** @var non-empty-array<string, array<int|string, string>> */
$call_map_data = require(dirname(__DIR__, 4) . '/dictionaries/CallMap.php');

self::$call_map = [];
$call_map = [];

foreach ($call_map as $key => $value) {
foreach ($call_map_data as $key => $value) {
$cased_key = strtolower($key);
self::$call_map[$cased_key] = $value;
$call_map[$cased_key] = $value;
}

self::$call_map = $call_map;

/**
* @var array<string, list<list<TaintKind::*>>>
* @var non-empty-array<string, non-empty-list<list<TaintKind::*>>>
*/
$taint_map = require(dirname(__DIR__, 4) . '/dictionaries/InternalTaintSinkMap.php');
$taint_map_data = require(dirname(__DIR__, 4) . '/dictionaries/InternalTaintSinkMap.php');

foreach ($taint_map as $key => $value) {
$taint_map = [];
foreach ($taint_map_data as $key => $value) {
$cased_key = strtolower($key);
self::$taint_sink_map[$cased_key] = $value;
$taint_map[$cased_key] = $value;
}

self::$taint_sink_map = $taint_map;

if (version_compare($analyzer_version, $current_version, '<')) {
// the following assumes both minor and major versions a single digits
for ($i = $current_version_int; $i > $analyzer_version_int && $i >= self::LOWEST_AVAILABLE_DELTA; --$i) {
Expand Down Expand Up @@ -408,6 +415,7 @@ public static function getCallMap(): array
}
}
}
assert(!empty(self::$call_map));

self::$loaded_php_major_version = $analyzer_major_version;
self::$loaded_php_minor_version = $analyzer_minor_version;
Expand Down