ovr / phpsa

Smart/Static Analyzer(sis) for PHP :bowtie::neckbeard:
Other
638 stars 77 forks source link

[Bug] False positive [undefined-variable] PassedByReference parameter #314

Open algo13 opened 7 years ago

algo13 commented 7 years ago

Moved from #298

<?php
function testUndefinedRefParam($subject)
{
    // Notice:  You are trying to use an undefined variable $matches [undefined-variable]
    if (preg_match('/$([a-zA-Z0-9_]+)/', $subject, $matches)) {
        echo "test\n";
    }
}
algo13 commented 7 years ago

That's a difficult problem...

Although you can obtain a list of parameters passed by reference of built-in functions, it can not judge whether it is assignment(e.g. preg_match) or change(e.g. each).

$info = [];
foreach (get_defined_functions()['internal'] as $internal) {
    foreach ((new \ReflectionFunction($internal))->getParameters() as $index => $param) {
        if ($param->isPassedByReference()) {
            if (!isset($info[$internal])) {
                $info[$internal] = [];
            }
            $info[$internal][] = $index;
        }
    }
}
foreach ($info as $name => $indexes) {
    echo "$name => [", implode(', ', $indexes), "]\n";
}

e.g. (PHP7.1.1 on windows(Non-Extensions))

each => [0]
preg_match => [2]
preg_match_all => [2]
preg_replace => [4]
preg_replace_callback => [4]
preg_replace_callback_array => [3]
preg_filter => [4]
getimagesize => [1]
getimagesizefromstring => [1]
str_replace => [3]
str_ireplace => [3]
similar_text => [2]
parse_str => [1]
sscanf => [2]
fscanf => [2]
exec => [1, 2]
system => [1]
passthru => [1]
proc_open => [2]
getopt => [2]
headers_sent => [0, 1]
dns_get_mx => [1, 2]
getmxrr => [1, 2]
dns_get_record => [2, 3]
settype => [0]
is_callable => [2]
stream_select => [0, 1, 2]
stream_socket_client => [1, 2]
stream_socket_server => [1, 2]
stream_socket_accept => [2]
stream_socket_recvfrom => [3]
flock => [2]
fsockopen => [2, 3]
pfsockopen => [2, 3]
ksort => [0]
krsort => [0]
natsort => [0]
natcasesort => [0]
asort => [0]
arsort => [0]
sort => [0]
rsort => [0]
usort => [0]
uasort => [0]
uksort => [0]
shuffle => [0]
array_walk => [0]
array_walk_recursive => [0]
end => [0]
prev => [0]
next => [0]
reset => [0]
extract => [0]
array_multisort => [0, 1, 2, 3]
array_push => [0]
array_pop => [0]
array_shift => [0]
array_unshift => [0]
array_splice => [0]
xml_parse_into_struct => [2, 3]
armoour commented 6 years ago

When i try to use $_POST, the same error shows;