mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix #699 - prevent stubs from overriding known functions
This commit is contained in:
parent
383f706d6b
commit
6b3759a266
@ -514,6 +514,28 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
|
||||
$this->file_storage->declaring_constants[$const->name->name] = $this->file_path;
|
||||
}
|
||||
}
|
||||
} elseif ($this->codebase->register_global_functions && $node instanceof PhpParser\Node\Stmt\If_) {
|
||||
if ($node->cond instanceof PhpParser\Node\Expr\BooleanNot) {
|
||||
if ($node->cond->expr instanceof PhpParser\Node\Expr\FuncCall
|
||||
&& $node->cond->expr->name instanceof PhpParser\Node\Name
|
||||
) {
|
||||
if ($node->cond->expr->name->parts === ['function_exists']
|
||||
&& isset($node->cond->expr->args[0])
|
||||
&& $node->cond->expr->args[0]->value instanceof PhpParser\Node\Scalar\String_
|
||||
&& function_exists($node->cond->expr->args[0]->value->value)
|
||||
) {
|
||||
return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
|
||||
}
|
||||
|
||||
if ($node->cond->expr->name->parts === ['class_exists']
|
||||
&& isset($node->cond->expr->args[0])
|
||||
&& $node->cond->expr->args[0]->value instanceof PhpParser\Node\Scalar\String_
|
||||
&& class_exists($node->cond->expr->args[0]->value->value, false)
|
||||
) {
|
||||
return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,7 +894,7 @@ class AnnotationTest extends TestCase
|
||||
|
||||
$arr["a"]()',
|
||||
],
|
||||
'magicMethodAnnotation' => [
|
||||
'magicMethodValidAnnotations' => [
|
||||
'<?php
|
||||
class Parent {
|
||||
public function __call() {}
|
||||
@ -915,6 +915,7 @@ class AnnotationTest extends TestCase
|
||||
|
||||
$a = $child->getString();
|
||||
$child->setInteger(4);
|
||||
/** @psalm-suppress MixedAssignment */
|
||||
$b = $child->setString(5);
|
||||
$c = $child->getBool("hello");
|
||||
$d = $child->getArray();
|
||||
@ -927,7 +928,6 @@ class AnnotationTest extends TestCase
|
||||
'$d' => 'array<mixed, string|int>',
|
||||
'$e' => 'callable():string',
|
||||
],
|
||||
'error_levels' => ['MixedAssignment'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -19,6 +19,14 @@ class ConfigTest extends TestCase
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$config = new TestConfig();
|
||||
|
||||
if (!defined('PSALM_VERSION')) {
|
||||
define('PSALM_VERSION', '2.0.0');
|
||||
}
|
||||
|
||||
if (!defined('PHP_PARSER_VERSION')) {
|
||||
define('PHP_PARSER_VERSION', '4.0.0');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -437,6 +445,38 @@ class ConfigTest extends TestCase
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testPolyfilledFunction()
|
||||
{
|
||||
$this->project_checker = $this->getProjectCheckerWithConfig(
|
||||
TestConfig::loadFromXML(
|
||||
dirname(__DIR__),
|
||||
'<?xml version="1.0"?>
|
||||
<psalm>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
|
||||
<stubs>
|
||||
<file name="tests/stubs/polyfill.php" />
|
||||
</stubs>
|
||||
</psalm>'
|
||||
)
|
||||
);
|
||||
|
||||
$file_path = getcwd() . '/src/somefile.php';
|
||||
|
||||
$this->addFile(
|
||||
$file_path,
|
||||
'<?php
|
||||
$a = random_bytes(16);'
|
||||
);
|
||||
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
|
11
tests/stubs/polyfill.php
Normal file
11
tests/stubs/polyfill.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
if (!function_exists("random_bytes")) {
|
||||
/**
|
||||
* @param int $bytes
|
||||
* @return void
|
||||
*/
|
||||
function random_bytes($bytes)
|
||||
{
|
||||
throw new \Exception("bad");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user