diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php index e280ff8d..76ea6043 100644 --- a/src/lint/linter/ArcanistXHPASTLinter.php +++ b/src/lint/linter/ArcanistXHPASTLinter.php @@ -64,6 +64,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { const LINT_CLASS_NAME_LITERAL = 62; const LINT_USELESS_OVERRIDING_METHOD = 63; const LINT_NO_PARENT_SCOPE = 64; + const LINT_ALIAS_FUNCTION = 65; private $blacklistedFunctions = array(); private $naminghook; @@ -200,6 +201,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { => pht('Useless Overriding Method'), self::LINT_NO_PARENT_SCOPE => pht('No Parent Scope'), + self::LINT_ALIAS_FUNCTION + => pht('Alias Functions'), ); } @@ -251,6 +254,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { self::LINT_LOWERCASE_FUNCTIONS => $advice, self::LINT_CLASS_NAME_LITERAL => $advice, self::LINT_USELESS_OVERRIDING_METHOD => $advice, + self::LINT_ALIAS_FUNCTION => $advice, ); } @@ -318,7 +322,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { public function getVersion() { // The version number should be incremented whenever a new rule is added. - return '26'; + return '27'; } protected function resolveFuture($path, Future $future) { @@ -409,6 +413,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { 'lintClassNameLiteral' => self::LINT_CLASS_NAME_LITERAL, 'lintUselessOverridingMethods' => self::LINT_USELESS_OVERRIDING_METHOD, 'lintNoParentScope' => self::LINT_NO_PARENT_SCOPE, + 'lintAliasFunctions' => self::LINT_ALIAS_FUNCTION, ); foreach ($method_codes as $method => $codes) { @@ -3891,6 +3896,210 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { } } + private function lintAliasFunctions(XHPASTNode $root) { + static $aliases = array( + '_' => 'gettext', + 'chop' => 'rtrim', + 'close' => 'closedir', + 'com_get' => 'com_propget', + 'com_propset' => 'com_propput', + 'com_set' => 'com_propput', + 'die' => 'exit', + 'diskfreespace' => 'disk_free_space', + 'doubleval' => 'floatval', + 'drawarc' => 'swfshape_drawarc', + 'drawcircle' => 'swfshape_drawcircle', + 'drawcubic' => 'swfshape_drawcubic', + 'drawcubicto' => 'swfshape_drawcubicto', + 'drawcurve' => 'swfshape_drawcurve', + 'drawcurveto' => 'swfshape_drawcurveto', + 'drawglyph' => 'swfshape_drawglyph', + 'drawline' => 'swfshape_drawline', + 'drawlineto' => 'swfshape_drawlineto', + 'fbsql' => 'fbsql_db_query', + 'fputs' => 'fwrite', + 'gzputs' => 'gzwrite', + 'i18n_convert' => 'mb_convert_encoding', + 'i18n_discover_encoding' => 'mb_detect_encoding', + 'i18n_http_input' => 'mb_http_input', + 'i18n_http_output' => 'mb_http_output', + 'i18n_internal_encoding' => 'mb_internal_encoding', + 'i18n_ja_jp_hantozen' => 'mb_convert_kana', + 'i18n_mime_header_decode' => 'mb_decode_mimeheader', + 'i18n_mime_header_encode' => 'mb_encode_mimeheader', + 'imap_create' => 'imap_createmailbox', + 'imap_fetchtext' => 'imap_body', + 'imap_getmailboxes' => 'imap_list_full', + 'imap_getsubscribed' => 'imap_lsub_full', + 'imap_header' => 'imap_headerinfo', + 'imap_listmailbox' => 'imap_list', + 'imap_listsubscribed' => 'imap_lsub', + 'imap_rename' => 'imap_renamemailbox', + 'imap_scan' => 'imap_listscan', + 'imap_scanmailbox' => 'imap_listscan', + 'ini_alter' => 'ini_set', + 'is_double' => 'is_float', + 'is_integer' => 'is_int', + 'is_long' => 'is_int', + 'is_real' => 'is_float', + 'is_writeable' => 'is_writable', + 'join' => 'implode', + 'key_exists' => 'array_key_exists', + 'ldap_close' => 'ldap_unbind', + 'magic_quotes_runtime' => 'set_magic_quotes_runtime', + 'mbstrcut' => 'mb_strcut', + 'mbstrlen' => 'mb_strlen', + 'mbstrpos' => 'mb_strpos', + 'mbstrrpos' => 'mb_strrpos', + 'mbsubstr' => 'mb_substr', + 'ming_setcubicthreshold' => 'ming_setCubicThreshold', + 'ming_setscale' => 'ming_setScale', + 'msql' => 'msql_db_query', + 'msql_createdb' => 'msql_create_db', + 'msql_dbname' => 'msql_result', + 'msql_dropdb' => 'msql_drop_db', + 'msql_fieldflags' => 'msql_field_flags', + 'msql_fieldlen' => 'msql_field_len', + 'msql_fieldname' => 'msql_field_name', + 'msql_fieldtable' => 'msql_field_table', + 'msql_fieldtype' => 'msql_field_type', + 'msql_freeresult' => 'msql_free_result', + 'msql_listdbs' => 'msql_list_dbs', + 'msql_listfields' => 'msql_list_fields', + 'msql_listtables' => 'msql_list_tables', + 'msql_numfields' => 'msql_num_fields', + 'msql_numrows' => 'msql_num_rows', + 'msql_regcase' => 'sql_regcase', + 'msql_selectdb' => 'msql_select_db', + 'msql_tablename' => 'msql_result', + 'mssql_affected_rows' => 'sybase_affected_rows', + 'mssql_close' => 'sybase_close', + 'mssql_connect' => 'sybase_connect', + 'mssql_data_seek' => 'sybase_data_seek', + 'mssql_fetch_array' => 'sybase_fetch_array', + 'mssql_fetch_field' => 'sybase_fetch_field', + 'mssql_fetch_object' => 'sybase_fetch_object', + 'mssql_fetch_row' => 'sybase_fetch_row', + 'mssql_field_seek' => 'sybase_field_seek', + 'mssql_free_result' => 'sybase_free_result', + 'mssql_get_last_message' => 'sybase_get_last_message', + 'mssql_min_client_severity' => 'sybase_min_client_severity', + 'mssql_min_error_severity' => 'sybase_min_error_severity', + 'mssql_min_message_severity' => 'sybase_min_message_severity', + 'mssql_min_server_severity' => 'sybase_min_server_severity', + 'mssql_num_fields' => 'sybase_num_fields', + 'mssql_num_rows' => 'sybase_num_rows', + 'mssql_pconnect' => 'sybase_pconnect', + 'mssql_query' => 'sybase_query', + 'mssql_result' => 'sybase_result', + 'mssql_select_db' => 'sybase_select_db', + 'multcolor' => 'swfdisplayitem_multColor', + 'mysql' => 'mysql_db_query', + 'mysql_createdb' => 'mysql_create_db', + 'mysql_db_name' => 'mysql_result', + 'mysql_dbname' => 'mysql_result', + 'mysql_dropdb' => 'mysql_drop_db', + 'mysql_fieldflags' => 'mysql_field_flags', + 'mysql_fieldlen' => 'mysql_field_len', + 'mysql_fieldname' => 'mysql_field_name', + 'mysql_fieldtable' => 'mysql_field_table', + 'mysql_fieldtype' => 'mysql_field_type', + 'mysql_freeresult' => 'mysql_free_result', + 'mysql_listdbs' => 'mysql_list_dbs', + 'mysql_listfields' => 'mysql_list_fields', + 'mysql_listtables' => 'mysql_list_tables', + 'mysql_numfields' => 'mysql_num_fields', + 'mysql_numrows' => 'mysql_num_rows', + 'mysql_selectdb' => 'mysql_select_db', + 'mysql_tablename' => 'mysql_result', + 'ociassignelem' => 'OCI-Collection::assignElem', + 'ocibindbyname' => 'oci_bind_by_name', + 'ocicancel' => 'oci_cancel', + 'ocicloselob' => 'OCI-Lob::close', + 'ocicollappend' => 'OCI-Collection::append', + 'ocicollassign' => 'OCI-Collection::assign', + 'ocicollmax' => 'OCI-Collection::max', + 'ocicollsize' => 'OCI-Collection::size', + 'ocicolltrim' => 'OCI-Collection::trim', + 'ocicolumnisnull' => 'oci_field_is_null', + 'ocicolumnname' => 'oci_field_name', + 'ocicolumnprecision' => 'oci_field_precision', + 'ocicolumnscale' => 'oci_field_scale', + 'ocicolumnsize' => 'oci_field_size', + 'ocicolumntype' => 'oci_field_type', + 'ocicolumntyperaw' => 'oci_field_type_raw', + 'ocicommit' => 'oci_commit', + 'ocidefinebyname' => 'oci_define_by_name', + 'ocierror' => 'oci_error', + 'ociexecute' => 'oci_execute', + 'ocifetch' => 'oci_fetch', + 'ocifetchinto' => 'oci_fetch_array(),', + 'ocifetchstatement' => 'oci_fetch_all', + 'ocifreecollection' => 'OCI-Collection::free', + 'ocifreecursor' => 'oci_free_statement', + 'ocifreedesc' => 'oci_free_descriptor', + 'ocifreestatement' => 'oci_free_statement', + 'ocigetelem' => 'OCI-Collection::getElem', + 'ociinternaldebug' => 'oci_internal_debug', + 'ociloadlob' => 'OCI-Lob::load', + 'ocilogon' => 'oci_connect', + 'ocinewcollection' => 'oci_new_collection', + 'ocinewcursor' => 'oci_new_cursor', + 'ocinewdescriptor' => 'oci_new_descriptor', + 'ocinlogon' => 'oci_new_connect', + 'ocinumcols' => 'oci_num_fields', + 'ociparse' => 'oci_parse', + 'ocipasswordchange' => 'oci_password_change', + 'ociplogon' => 'oci_pconnect', + 'ociresult' => 'oci_result', + 'ocirollback' => 'oci_rollback', + 'ocisavelob' => 'OCI-Lob::save', + 'ocisavelobfile' => 'OCI-Lob::import', + 'ociserverversion' => 'oci_server_version', + 'ocisetprefetch' => 'oci_set_prefetch', + 'ocistatementtype' => 'oci_statement_type', + 'ociwritelobtofile' => 'OCI-Lob::export', + 'ociwritetemporarylob' => 'OCI-Lob::writeTemporary', + 'odbc_do' => 'odbc_exec', + 'odbc_field_precision' => 'odbc_field_len', + 'pdf_add_outline' => 'pdf_add_bookmark', + 'pg_clientencoding' => 'pg_client_encoding', + 'pg_setclientencoding' => 'pg_set_client_encoding', + 'pos' => 'current', + 'recode' => 'recode_string', + 'show_source' => 'highlight_file', + 'sizeof' => 'count', + 'snmpwalkoid' => 'snmprealwalk', + 'strchr' => 'strstr', + 'streammp3' => 'swfmovie_streamMp3', + 'swfaction' => 'swfaction_init', + 'swfbitmap' => 'swfbitmap_init', + 'swfbutton' => 'swfbutton_init', + 'swffill' => 'swffill_init', + 'swffont' => 'swffont_init', + 'swfgradient' => 'swfgradient_init', + 'swfmorph' => 'swfmorph_init', + 'swfmovie' => 'swfmovie_init', + 'swfshape' => 'swfshape_init', + 'swfsprite' => 'swfsprite_init', + 'swftext' => 'swftext_init', + 'swftextfield' => 'swftextfield_init', + 'xptr_new_context' => 'xpath_new_context', + ); + + $functions = $this->getFunctionCalls($root, array_keys($aliases)); + + foreach ($functions as $function) { + $function_name = $function->getChildByIndex(0); + + $this->raiseLintAtNode( + $function_name, + self::LINT_ALIAS_FUNCTION, + pht('Alias functions should be avoided.'), + $aliases[$function_name->getConcreteString()]); + } + } + /** * Retrieve all calls to some specified function(s). diff --git a/src/lint/linter/__tests__/xhpast/alias-functions.lint-test b/src/lint/linter/__tests__/xhpast/alias-functions.lint-test new file mode 100644 index 00000000..0ef87006 --- /dev/null +++ b/src/lint/linter/__tests__/xhpast/alias-functions.lint-test @@ -0,0 +1,14 @@ +