mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 06:42:41 +01:00
Find classes used in call_user_func()
Summary: Also fix false positive for call_user_func('C::f'). Also fix false positive for call_user_func("$f"). Also centralize handling of magic classes. Test Plan: call_user_func("$f"); call_user_func('C::f'); call_user_func(array('C', 'f')); call_user_func(array(1 => 'f', 0 => 'C')); Linted Phabricator. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D6137
This commit is contained in:
parent
5336f4bcf0
commit
f3e32d8366
2 changed files with 23 additions and 21 deletions
|
@ -21,7 +21,7 @@ final class PhutilLibraryMapBuilder {
|
|||
const LIBRARY_MAP_VERSION = 2;
|
||||
|
||||
const SYMBOL_CACHE_VERSION_KEY = '__symbol_cache_version__';
|
||||
const SYMBOL_CACHE_VERSION = 9;
|
||||
const SYMBOL_CACHE_VERSION = 10;
|
||||
|
||||
|
||||
/* -( Mapping libphutil Libraries )---------------------------------------- */
|
||||
|
|
|
@ -143,6 +143,7 @@ foreach ($functions as $function) {
|
|||
//
|
||||
// - Explicit Call
|
||||
// - String literal passed to call_user_func() or call_user_func_array()
|
||||
// - String literal in array literal in call_user_func()/call_user_func_array()
|
||||
//
|
||||
// TODO: Possibly support these:
|
||||
//
|
||||
|
@ -170,10 +171,22 @@ foreach ($calls as $call) {
|
|||
continue;
|
||||
}
|
||||
$symbol = array_shift($params);
|
||||
$type = 'function';
|
||||
$symbol_value = $symbol->getStringLiteralValue();
|
||||
if ($symbol_value) {
|
||||
$pos = strpos($symbol_value, '::');
|
||||
if ($pos) {
|
||||
$type = 'class';
|
||||
$symbol_value = substr($symbol_value, 0, $pos);
|
||||
} else if ($symbol->getTypeName() == 'n_ARRAY_LITERAL') {
|
||||
try {
|
||||
$type = 'class';
|
||||
$symbol_value = idx($symbol->evalStatic(), 0);
|
||||
} catch (Exception $ex) {
|
||||
}
|
||||
}
|
||||
if ($symbol_value && strpos($symbol_value, '$') === false) {
|
||||
$need[] = array(
|
||||
'type' => 'function',
|
||||
'type' => $type,
|
||||
'name' => $symbol_value,
|
||||
'symbol' => $symbol,
|
||||
);
|
||||
|
@ -218,7 +231,6 @@ foreach ($classes as $class) {
|
|||
// - instanceof
|
||||
// - catch
|
||||
// - String literal in ReflectionClass().
|
||||
// - String literal in array literal in call_user_func()/call_user_func_array()
|
||||
|
||||
|
||||
// This is "class X ... { ... }".
|
||||
|
@ -237,12 +249,6 @@ foreach ($classes as $class) {
|
|||
}
|
||||
}
|
||||
|
||||
$magic_names = array(
|
||||
'static' => true,
|
||||
'parent' => true,
|
||||
'self' => true,
|
||||
);
|
||||
|
||||
// This is "new X()".
|
||||
$uses_of_new = $root->selectDescendantsOfType('n_NEW');
|
||||
foreach ($uses_of_new as $new_operator) {
|
||||
|
@ -251,10 +257,6 @@ foreach ($uses_of_new as $new_operator) {
|
|||
$name->getTypeName() == 'n_VARIABLE_VARIABLE') {
|
||||
continue;
|
||||
}
|
||||
$name_concrete = strtolower($name->getConcreteString());
|
||||
if (isset($magic_names[$name_concrete])) {
|
||||
continue;
|
||||
}
|
||||
$need[] = array(
|
||||
'type' => 'class',
|
||||
'symbol' => $name,
|
||||
|
@ -268,10 +270,6 @@ foreach ($static_uses as $static_use) {
|
|||
if ($name->getTypeName() != 'n_CLASS_NAME') {
|
||||
continue;
|
||||
}
|
||||
$name_concrete = strtolower($name->getConcreteString());
|
||||
if (isset($magic_names[$name_concrete])) {
|
||||
continue;
|
||||
}
|
||||
$need[] = array(
|
||||
'type' => 'class/interface',
|
||||
'symbol' => $name,
|
||||
|
@ -434,6 +432,10 @@ function phutil_symbols_get_builtins() {
|
|||
|
||||
return array(
|
||||
'class' => array_fill_keys($builtin['classes'], true) + array(
|
||||
'static' => true,
|
||||
'parent' => true,
|
||||
'self' => true,
|
||||
|
||||
'PhutilBootloader' => true,
|
||||
),
|
||||
'function' => array_filter(
|
||||
|
|
Loading…
Reference in a new issue