files = $files; $this->analyzer = $analyzer; } /** @return list */ public function ids(): array { return CodeFindingAnalyzer::ids(); } /** @return array */ public function analyze( string $check_id, int $run_id, string $timestamp ): array { $definitions = $this->definitions(); if ( ! isset( $definitions[ $check_id ] ) ) { throw new InvalidArgumentException( 'code_analyzer_not_implemented' ); } if ( 'code.namespace_collisions' === $check_id ) { $summary = $this->files->symbol_summary( $run_id ); } elseif ( 'code.ownership_reproducibility' === $check_id ) { $summary = $this->files->ownership_summary( $run_id ); } else { $definition = $definitions[ $check_id ]; $summary = $this->files->signal_summary( $run_id, $definition['extensions'], $definition['signals'] ); } return $this->analyzer->analyze( $check_id, $summary, $timestamp ); } /** @return array,signals:list}> */ private function definitions(): array { $php = array( 'php', 'inc', 'phtml' ); return array( 'code.syntax_compatibility' => array( 'extensions' => $php, 'signals' => array( 'syntax.parse_error', 'compat.attribute', 'compat.match', 'compat.nullsafe_object_operator', 'compat.enum', 'compat.readonly' ), ), 'code.input_output_security' => array( 'extensions' => $php, 'signals' => array( 'io.input_output_cooccurrence' ), ), 'code.database_security' => array( 'extensions' => $php, 'signals' => array( 'database.unprepared_call_signal' ), ), 'code.dynamic_execution' => array( 'extensions' => $php, 'signals' => array( 'dynamic.eval', 'dynamic.assert', 'dynamic.create_function', 'dynamic.shell_call', 'dynamic.shell_backtick' ), ), 'code.filesystem_uploads' => array( 'extensions' => $php, 'signals' => array( 'filesystem.write_call', 'filesystem.delete_call', 'filesystem.move_call', 'filesystem.upload_move', 'filesystem.upload_handler' ), ), 'code.outbound_requests' => array( 'extensions' => array( 'php', 'inc', 'phtml', 'js', 'mjs', 'cjs' ), 'signals' => array( 'outbound.wp_http', 'outbound.curl', 'outbound.socket', 'outbound.fetch', 'outbound.xhr' ), ), 'code.secret_signals' => array( 'extensions' => array( 'php', 'inc', 'phtml', 'js', 'mjs', 'cjs', 'css' ), 'signals' => array( 'secret.credential_literal', 'secret.private_key_material' ), ), 'code.hot_paths' => array( 'extensions' => $php, 'signals' => array( 'hot.hook_registration' ), ), 'code.namespace_collisions' => array( 'extensions' => $php, 'signals' => array(), ), 'code.frontend_residue' => array( 'extensions' => array( 'js', 'mjs', 'cjs', 'css' ), 'signals' => array( 'frontend.console', 'frontend.debugger', 'frontend.eval', 'frontend.document_write', 'frontend.source_map', 'frontend.old_ie_hack' ), ), 'code.ownership_reproducibility' => array( 'extensions' => array( 'metadata' ), 'signals' => array(), ), ); } }