Skip to content

Commit

Permalink
Taint flows through preg_replace_callback
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jun 23, 2020
1 parent f72b609 commit f46236a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Psalm/Internal/Stubs/CoreGenericFunctions.phpstub
Expand Up @@ -612,6 +612,17 @@ function str_replace($search, $replace, $subject, &$count = null) {}
*/
function preg_replace($search, $replace, $subject, int $limit = -1, &$count = null) {}

/**
* @param string|string[] $search
* @param callable(array<int, string>):string $replace
* @param string|array<string|int|float> $subject
* @param int $count
* @return ($subject is array ? array<string> : string)
*
* @psalm-flow ($subject) -> return
*/
function preg_replace_callback($search, $replace, $subject, int $limit = -1, &$count = null) {}

/**
* @psalm-pure
*
Expand Down
26 changes: 26 additions & 0 deletions tests/TaintTest.php
Expand Up @@ -1749,4 +1749,30 @@ public static function slugify(string $url) : string {

$this->analyzeFile('somefile.php', new Context());
}

public function testTaintThroughPregReplaceCallback() : void
{
$this->expectException(\Psalm\Exception\CodeException::class);
$this->expectExceptionMessage('TaintedInput');

$this->project_analyzer->trackTaintedInputs();

$this->addFile(
'somefile.php',
'<?php
$a = $_GET["bad"];
$b = preg_replace_callback(
\'/foo/\',
function (array $matches) : string {
return $matches[1];
},
$a
);
echo $b;'
);

$this->analyzeFile('somefile.php', new Context());
}
}

0 comments on commit f46236a

Please sign in to comment.