Skip to content
Permalink
Browse files

Add better typing

  • Loading branch information...
muglug committed Aug 14, 2019
1 parent c3949e3 commit 600999a3a8f40752be1647f2170dc7c239c264dd
@@ -39,7 +39,6 @@
use function substr;
use function count;
use function in_array;
use Psalm\Internal\Taint\TypeSource;
/**
* @internal
@@ -42,7 +42,7 @@
use function array_keys;
use function end;
use function array_diff;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -593,7 +593,7 @@ function (FunctionLikeParameter $p) {
}
if ($cased_method_id && $codebase->taint) {
$type_source = TypeSource::getForMethodArgument(
$type_source = Source::getForMethodArgument(
$cased_method_id,
$offset,
$function_param->location,
@@ -42,7 +42,8 @@
use function in_array;
use function strtolower;
use function explode;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Sink;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -940,6 +941,9 @@ public static function analyzeInstance(
return null;
}
/**
* @psalm-suppress UnusedVariable
*/
private static function taintProperty(
StatementsAnalyzer $statements_analyzer,
PhpParser\Node\Expr\PropertyFetch $stmt,
@@ -952,22 +956,34 @@ private static function taintProperty(
return;
}
$method_source = new TypeSource(
$code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
$method_sink = new Sink(
$property_id,
new CodeLocation($statements_analyzer->getSource(), $stmt)
$code_location
);
if ($assignment_value_type->tainted) {
$method_source->taint = $assignment_value_type->tainted;
$method_sink->taint = $assignment_value_type->tainted;
}
if ($codebase->taint->hasPreviousSink($method_source)) {
if ($codebase->taint->hasPreviousSink($method_sink)) {
if ($assignment_value_type->sources) {
$codebase->taint->addSinks(
$statements_analyzer,
$assignment_value_type->sources,
new CodeLocation($statements_analyzer->getSource(), $stmt),
$method_source
\array_map(
function (Source $assignment_source) use ($method_sink) {
$new_sink = new Sink(
$assignment_source->id,
$assignment_source->code_location
);
$new_sink->children = [$method_sink];
return $new_sink;
},
$assignment_value_type->sources
)
);
}
}
@@ -977,15 +993,26 @@ private static function taintProperty(
if (($previous_source = $codebase->taint->hasPreviousSource($type_source))
|| $assignment_value_type->tainted
) {
if ($previous_source) {
$method_source->taint = $previous_source->taint;
if (!$previous_source) {
$previous_source = new Source(
$type_source->id,
$type_source->code_location
);
$previous_source->taint = $assignment_value_type->tainted;
}
$new_source = new Source(
$property_id,
$code_location
);
$new_source->parents = [$previous_source];
$new_source->taint = $previous_source->taint;
$codebase->taint->addSources(
$statements_analyzer,
[$method_source],
new CodeLocation($statements_analyzer->getSource(), $stmt),
$type_source
[$new_source]
);
}
}
@@ -47,7 +47,7 @@
use function array_search;
use function array_keys;
use function in_array;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -1145,7 +1145,7 @@ function (PhpParser\Node\Arg $arg) {
);
$return_type_candidate->sources = [
new TypeSource(strtolower($method_id), new CodeLocation($source, $stmt->name))
new Source(strtolower($method_id), new CodeLocation($source, $stmt->name))
];
$return_type_location = $codebase->methods->getMethodReturnTypeLocation(
@@ -1221,7 +1221,7 @@ function (Assertion $assertion) use ($class_template_params) : Assertion {
if ($method_storage && $method_storage->pure) {
$code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
$method_source = new TypeSource(
$method_source = new Source(
strtolower(
$method_id
. '-' . $code_location->file_name
@@ -1230,7 +1230,7 @@ function (Assertion $assertion) use ($class_template_params) : Assertion {
new CodeLocation($source, $stmt->name)
);
} else {
$method_source = new TypeSource(
$method_source = new Source(
strtolower($method_id),
new CodeLocation($source, $stmt->name)
);
@@ -31,7 +31,7 @@
use function is_string;
use function strlen;
use function substr;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -994,7 +994,7 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
if ($method_storage && $method_storage->pure) {
$code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
$method_source = new TypeSource(
$method_source = new Source(
strtolower(
$method_id
. '-' . $code_location->file_name
@@ -1003,7 +1003,7 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
new CodeLocation($source, $stmt->name)
);
} else {
$method_source = new TypeSource(
$method_source = new Source(
strtolower($method_id),
new CodeLocation($source, $stmt->name)
);
@@ -1016,7 +1016,7 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
$specialized_sources = [];
foreach ($suffixes as $suffix) {
$specialized_sources[] = new TypeSource(
$specialized_sources[] = new Source(
$method_source->id . '-' . $suffix,
$method_source->code_location,
$tainted_source->taint
@@ -10,7 +10,8 @@
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TypeAnalyzer;
use Psalm\Internal\Codebase\CallMap;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Sink;
use Psalm\Internal\Taint\Source;
use Psalm\Internal\Type\TypeCombination;
use Psalm\CodeLocation;
use Psalm\Context;
@@ -2785,15 +2786,15 @@ private static function processTaintedness(
return;
}
$method_source = TypeSource::getForMethodArgument(
$method_sink = Sink::getForMethodArgument(
$cased_method_id,
$argument_offset,
$code_location
);
$found_sink = null;
if (($function_param->sink || ($found_sink = $codebase->taint->hasPreviousSink($method_source)))
if (($function_param->sink || ($found_sink = $codebase->taint->hasPreviousSink($method_sink)))
&& $input_type->sources
) {
$all_possible_sinks = [];
@@ -2803,7 +2804,14 @@ private static function processTaintedness(
continue;
}
$all_possible_sinks[] = $source;
$base_sink = new Sink(
$source->id,
$source->code_location
);
$base_sink->children = [$method_sink];
$all_possible_sinks[] = $base_sink;
if (strpos($source->id, '::') && strpos($source->id, '#')) {
list($fq_classlike_name, $method_name) = explode('::', $source->id);
@@ -2815,28 +2823,31 @@ private static function processTaintedness(
$class_storage = $codebase->classlike_storage_provider->get($fq_classlike_name);
foreach ($class_storage->dependent_classlikes as $dependent_classlike => $_) {
$new_sink = TypeSource::getForMethodArgument(
$new_sink = Sink::getForMethodArgument(
$dependent_classlike . '::' . $method_name,
(int) $method_name_parts[1] - 1,
$code_location,
null
);
$new_sink->children = [$method_sink];
$new_sink->taint = $found_sink ? $found_sink->taint : $function_param->sink;
$all_possible_sinks[] = $new_sink;
}
if (isset($class_storage->overridden_method_ids[$method_name])) {
foreach ($class_storage->overridden_method_ids[$method_name] as $parent_method_id) {
$new_sink = TypeSource::getForMethodArgument(
$new_sink = Sink::getForMethodArgument(
$parent_method_id,
(int) $method_name_parts[1] - 1,
$code_location,
null
);
$new_sink->taint = $found_sink ? $found_sink->taint : $function_param->sink;
$new_sink->children = [$method_sink];
$all_possible_sinks[] = $new_sink;
}
@@ -2846,9 +2857,7 @@ private static function processTaintedness(
$codebase->taint->addSinks(
$statements_analyzer,
$all_possible_sinks,
$code_location,
$method_source
$all_possible_sinks
);
}
@@ -2857,11 +2866,17 @@ private static function processTaintedness(
&& ($function_param->sink & $input_type->tainted)
&& $input_type->sources
) {
$method_sink = Sink::getForMethodArgument(
$cased_method_id,
$argument_offset,
$code_location
);
foreach ($input_type->sources as $input_source) {
if (IssueBuffer::accepts(
new TaintedInput(
'in path ' . $codebase->taint->getPredecessorPath($input_source)
. ' out path ' . $codebase->taint->getSuccessorPath($method_source),
. ' out path ' . $codebase->taint->getSuccessorPath($method_sink),
$code_location
),
$statements_analyzer->getSuppressedIssues()
@@ -2875,22 +2890,30 @@ private static function processTaintedness(
strtolower($cased_method_id . '#' . ($argument_offset + 1)),
$function_location->file_name . ':' . $function_location->raw_file_start
);
$method_source = TypeSource::getForMethodArgument(
$cased_method_id,
$argument_offset,
$code_location,
$function_location
);
}
foreach ($input_type->sources as $type_source) {
if ($codebase->taint->hasPreviousSource($type_source) || $input_type->tainted) {
if ($function_is_pure) {
$method_source = Source::getForMethodArgument(
$cased_method_id,
$argument_offset,
$code_location,
$function_location
);
} else {
$method_source = Source::getForMethodArgument(
$cased_method_id,
$argument_offset,
$code_location
);
}
$method_source->parents = [$type_source];
$codebase->taint->addSources(
$statements_analyzer,
[$method_source],
$code_location,
$type_source
[$method_source]
);
}
}
@@ -51,7 +51,7 @@
use function in_array;
use function is_int;
use function preg_match;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -164,7 +164,7 @@ public static function analyze(
if ($array_var_id === '$_GET' || $array_var_id === '$_POST' || $array_var_id === '$_COOKIE') {
$stmt->inferredType->tainted = (int) Type\Union::TAINTED_INPUT;
$stmt->inferredType->sources = [
new TypeSource(
new Source(
'$_GET',
new CodeLocation($statements_analyzer->getSource(), $stmt),
(int) Type\Union::TAINTED_INPUT
@@ -39,7 +39,7 @@
use function array_keys;
use function count;
use function explode;
use Psalm\Internal\Taint\TypeSource;
use Psalm\Internal\Taint\Source;
/**
* @internal
@@ -850,7 +850,7 @@ private static function processTaints(
$codebase = $statements_analyzer->getCodebase();
if ($codebase->taint) {
$method_source = new TypeSource(
$method_source = new Source(
$property_id,
new CodeLocation($statements_analyzer, $stmt->name)
);

0 comments on commit 600999a

Please sign in to comment.
You can’t perform that action at this time.