Skip to content

Commit

Permalink
Merge pull request vimeo#10136 from weirdan/extract-impure-functions-…
Browse files Browse the repository at this point in the history
…list
  • Loading branch information
weirdan committed Aug 21, 2023
2 parents d39a103 + e6aa3fd commit 357a0a3
Show file tree
Hide file tree
Showing 3 changed files with 282 additions and 118 deletions.
250 changes: 250 additions & 0 deletions dictionaries/ImpureFunctionsList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
<?php

namespace Psalm\Internal;

return [
// file io
'chdir' => true,
'chgrp' => true,
'chmod' => true,
'chown' => true,
'chroot' => true,
'copy' => true,
'file_get_contents' => true,
'file_put_contents' => true,
'opendir' => true,
'readdir' => true,
'closedir' => true,
'rewinddir' => true,
'scandir' => true,
'fopen' => true,
'fread' => true,
'fwrite' => true,
'fclose' => true,
'touch' => true,
'fpassthru' => true,
'fputs' => true,
'fscanf' => true,
'fseek' => true,
'flock' => true,
'ftruncate' => true,
'fprintf' => true,
'symlink' => true,
'mkdir' => true,
'unlink' => true,
'rename' => true,
'rmdir' => true,
'popen' => true,
'pclose' => true,
'fgetcsv' => true,
'fputcsv' => true,
'umask' => true,
'finfo_open' => true,
'finfo_close' => true,
'finfo_file' => true,
'stream_set_timeout' => true,
'fgets' => true,
'fflush' => true,
'move_uploaded_file' => true,
'file_exists' => true,
'realpath' => true,
'glob' => true,
'is_readable' => true,
'is_dir' => true,
'is_file' => true,
// stream/socket io
'stream_context_set_option' => true,
'socket_write' => true,
'stream_set_blocking' => true,
'socket_close' => true,
'socket_set_option' => true,
'stream_set_write_buffer' => true,
'stream_socket_enable_crypto' => true,
'stream_copy_to_stream' => true,
'stream_wrapper_register' => true,
'socket_connect' => true,
'socket_bind' => true,
'socket_set_block' => true,
'socket_set_nonblock' => true,
'socket_listen' => true,
// meta calls
'call_user_func' => true,
'call_user_func_array' => true,
'define' => true,
'create_function' => true,
// http
'header' => true,
'header_remove' => true,
'http_response_code' => true,
'setcookie' => true,
'setrawcookie' => true,
// output buffer
'ob_start' => true,
'ob_end_clean' => true,
'ob_get_clean' => true,
'readfile' => true,
'printf' => true,
'var_dump' => true,
'phpinfo' => true,
'ob_implicit_flush' => true,
'vprintf' => true,
// mcrypt
'mcrypt_generic_init' => true,
'mcrypt_generic_deinit' => true,
'mcrypt_module_close' => true,
// internal optimisation
'opcache_compile_file' => true,
'clearstatcache' => true,
// process-related
'pcntl_signal' => true,
'pcntl_alarm' => true,
'posix_kill' => true,
'cli_set_process_title' => true,
'pcntl_async_signals' => true,
'proc_close' => true,
'proc_nice' => true,
'proc_open' => true,
'proc_terminate' => true,
// curl
'curl_setopt' => true,
'curl_close' => true,
'curl_multi_add_handle' => true,
'curl_multi_remove_handle' => true,
'curl_multi_select' => true,
'curl_multi_close' => true,
'curl_setopt_array' => true,
// apc, apcu
'apc_store' => true,
'apc_delete' => true,
'apc_clear_cache' => true,
'apc_add' => true,
'apc_inc' => true,
'apc_dec' => true,
'apc_cas' => true,
'apcu_store' => true,
'apcu_delete' => true,
'apcu_clear_cache' => true,
'apcu_add' => true,
'apcu_inc' => true,
'apcu_dec' => true,
'apcu_cas' => true,
// gz
'gzwrite' => true,
'gzrewind' => true,
'gzseek' => true,
'gzclose' => true,
// newrelic
'newrelic_start_transaction' => true,
'newrelic_name_transaction' => true,
'newrelic_add_custom_parameter' => true,
'newrelic_add_custom_tracer' => true,
'newrelic_background_job' => true,
'newrelic_end_transaction' => true,
'newrelic_set_appname' => true,
// execution
'shell_exec' => true,
'exec' => true,
'system' => true,
'passthru' => true,
'pcntl_exec' => true,
// well-known functions
'libxml_use_internal_errors' => true,
'libxml_disable_entity_loader' => true,
'curl_exec' => true,
'mt_srand' => true,
'openssl_pkcs7_sign' => true,
'openssl_sign' => true,
'mt_rand' => true,
'rand' => true,
'random_int' => true,
'random_bytes' => true,
'wincache_ucache_delete' => true,
'wincache_ucache_set' => true,
'wincache_ucache_inc' => true,
'class_alias' => true,
'class_exists' => true, // impure by virtue of triggering autoloader
'enum_exists' => true, // impure by virtue of triggering autoloader
// php environment
'ini_set' => true,
'sleep' => true,
'usleep' => true,
'register_shutdown_function' => true,
'error_reporting' => true,
'register_tick_function' => true,
'unregister_tick_function' => true,
'set_error_handler' => true,
'user_error' => true,
'trigger_error' => true,
'restore_error_handler' => true,
'date_default_timezone_set' => true,
'assert_options' => true,
'setlocale' => true,
'set_exception_handler' => true,
'set_time_limit' => true,
'putenv' => true,
'spl_autoload_register' => true,
'spl_autoload_unregister' => true,
'microtime' => true,
'array_rand' => true,
'set_include_path' => true,
// logging
'openlog' => true,
'syslog' => true,
'error_log' => true,
'define_syslog_variables' => true,
// session
'session_id' => true,
'session_decode' => true,
'session_name' => true,
'session_set_cookie_params' => true,
'session_set_save_handler' => true,
'session_regenerate_id' => true,
'mb_internal_encoding' => true,
'session_start' => true,
'session_cache_limiter' => true,
// ldap
'ldap_set_option' => true,
// iterators
'rewind' => true,
'iterator_apply' => true,
'iterator_to_array' => true,
// mysqli
'mysqli_select_db' => true,
'mysqli_dump_debug_info' => true,
'mysqli_kill' => true,
'mysqli_multi_query' => true,
'mysqli_next_result' => true,
'mysqli_options' => true,
'mysqli_ping' => true,
'mysqli_query' => true,
'mysqli_report' => true,
'mysqli_rollback' => true,
'mysqli_savepoint' => true,
'mysqli_set_charset' => true,
'mysqli_ssl_set' => true,
'mysqli_close' => true,
// script execution
'ignore_user_abort' => true,
// ftp
'ftp_close' => true,
'ftp_pasv' => true,
// bcmath
'bcscale' => true,
// json
'json_last_error' => true,
// opcache
'opcache_compile_file' => true,
'opcache_get_configuration' => true,
'opcache_get_status' => true,
'opcache_invalidate' => true,
'opcache_is_script_cached' => true,
'opcache_reset' => true,
//gettext
'bindtextdomain' => true,
// hash
'hash_update' => true,
'hash_update_file' => true,
'hash_update_stream' => true,
// unserialize
'unserialize' => true,
];
119 changes: 1 addition & 118 deletions src/Psalm/Internal/Codebase/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,124 +405,7 @@ public function isCallMapFunctionPure(
?array $args,
bool &$must_use = true
): bool {
$impure_functions = [
// file io
'chdir', 'chgrp', 'chmod', 'chown', 'chroot', 'copy', 'file_get_contents', 'file_put_contents',
'opendir', 'readdir', 'closedir', 'rewinddir', 'scandir',
'fopen', 'fread', 'fwrite', 'fclose', 'touch', 'fpassthru', 'fputs', 'fscanf', 'fseek', 'flock',
'ftruncate', 'fprintf', 'symlink', 'mkdir', 'unlink', 'rename', 'rmdir', 'popen', 'pclose',
'fgetcsv', 'fputcsv', 'umask', 'finfo_open', 'finfo_close', 'finfo_file',
'stream_set_timeout', 'fgets', 'fflush', 'move_uploaded_file', 'file_exists', 'realpath', 'glob',
'is_readable', 'is_dir', 'is_file',

// stream/socket io
'stream_context_set_option', 'socket_write', 'stream_set_blocking', 'socket_close',
'socket_set_option', 'stream_set_write_buffer', 'stream_socket_enable_crypto', 'stream_copy_to_stream',
'stream_wrapper_register', 'socket_connect', 'socket_bind', 'socket_set_block', 'socket_set_nonblock',
'socket_listen',

// meta calls
'call_user_func', 'call_user_func_array', 'define', 'create_function',

// http
'header', 'header_remove', 'http_response_code', 'setcookie', 'setrawcookie',

// output buffer
'ob_start', 'ob_end_clean', 'ob_get_clean', 'readfile', 'printf', 'var_dump', 'phpinfo',
'ob_implicit_flush', 'vprintf',

// mcrypt
'mcrypt_generic_init', 'mcrypt_generic_deinit', 'mcrypt_module_close',

// internal optimisation
'opcache_compile_file', 'clearstatcache',

// process-related
'pcntl_signal', 'pcntl_alarm', 'posix_kill', 'cli_set_process_title', 'pcntl_async_signals', 'proc_close',
'proc_nice', 'proc_open', 'proc_terminate',

// curl
'curl_setopt', 'curl_close', 'curl_multi_add_handle', 'curl_multi_remove_handle',
'curl_multi_select', 'curl_multi_close', 'curl_setopt_array',

// apc, apcu
'apc_store', 'apc_delete', 'apc_clear_cache', 'apc_add', 'apc_inc', 'apc_dec', 'apc_cas',
'apcu_store', 'apcu_delete', 'apcu_clear_cache', 'apcu_add', 'apcu_inc', 'apcu_dec', 'apcu_cas',

// gz
'gzwrite', 'gzrewind', 'gzseek', 'gzclose',

// newrelic
'newrelic_start_transaction', 'newrelic_name_transaction', 'newrelic_add_custom_parameter',
'newrelic_add_custom_tracer', 'newrelic_background_job', 'newrelic_end_transaction',
'newrelic_set_appname',

// execution
'shell_exec', 'exec', 'system', 'passthru', 'pcntl_exec',

// well-known functions
'libxml_use_internal_errors', 'libxml_disable_entity_loader', 'curl_exec',
'mt_srand', 'openssl_pkcs7_sign', 'openssl_sign',
'mt_rand', 'rand', 'random_int', 'random_bytes',
'wincache_ucache_delete', 'wincache_ucache_set', 'wincache_ucache_inc',
'class_alias',
'class_exists', // impure by virtue of triggering autoloader
'enum_exists', // impure by virtue of triggering autoloader

// php environment
'ini_set', 'sleep', 'usleep', 'register_shutdown_function',
'error_reporting', 'register_tick_function', 'unregister_tick_function',
'set_error_handler', 'user_error', 'trigger_error', 'restore_error_handler',
'date_default_timezone_set', 'assert_options', 'setlocale',
'set_exception_handler', 'set_time_limit', 'putenv', 'spl_autoload_register',
'spl_autoload_unregister', 'microtime', 'array_rand', 'set_include_path',

// logging
'openlog', 'syslog', 'error_log', 'define_syslog_variables',

// session
'session_id', 'session_decode', 'session_name', 'session_set_cookie_params',
'session_set_save_handler', 'session_regenerate_id', 'mb_internal_encoding',
'session_start', 'session_cache_limiter',

// ldap
'ldap_set_option',

// iterators
'rewind', 'iterator_apply', 'iterator_to_array',

// mysqli
'mysqli_select_db', 'mysqli_dump_debug_info', 'mysqli_kill', 'mysqli_multi_query',
'mysqli_next_result', 'mysqli_options', 'mysqli_ping', 'mysqli_query', 'mysqli_report',
'mysqli_rollback', 'mysqli_savepoint', 'mysqli_set_charset', 'mysqli_ssl_set', 'mysqli_close',

// script execution
'ignore_user_abort',

// ftp
'ftp_close', 'ftp_pasv',

// bcmath
'bcscale',

// json
'json_last_error',

// opcache
'opcache_compile_file', 'opcache_get_configuration', 'opcache_get_status',
'opcache_invalidate', 'opcache_is_script_cached', 'opcache_reset',

//gettext
'bindtextdomain',

// hash
'hash_update', 'hash_update_file', 'hash_update_stream',

// unserialize
'unserialize',
];

if (in_array(strtolower($function_id), $impure_functions, true)) {
if (ImpureFunctionsList::isImpure($function_id)) {
return false;
}

Expand Down

0 comments on commit 357a0a3

Please sign in to comment.