1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-22 21:40:54 +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:
Jakub Vrana 2013-06-05 14:38:15 -07:00
parent 5336f4bcf0
commit f3e32d8366
2 changed files with 23 additions and 21 deletions

View file

@ -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 )---------------------------------------- */

View file

@ -141,12 +141,13 @@ foreach ($functions as $function) {
// Find functions used by this file. Uses:
//
// - Explicit Call
// - String literal passed to call_user_func() or call_user_func_array()
// - 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:
//
// - String literal in ReflectionFunction().
// - String literal in ReflectionFunction().
// This is "f();".
$calls = $root->selectDescendantsOfType('n_FUNCTION_CALL');
@ -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(