[MediaWiki-commits] [Gerrit] mediawiki...SecurityCheckPlugin[master]: Support loading hook information from extension.json
Brian Wolff has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/394092 ) Change subject: Support loading hook information from extension.json .. Support loading hook information from extension.json As of yet, nothing is done with hook info. Change-Id: I978302f5a6f18ab2070af4e296cdcd20faaa4a07 --- M README M src/MediaWikiSecurityCheckPlugin.php A tests/integration/json/Parser.php A tests/integration/json/expectedResults.txt A tests/integration/json/extension.json A tests/integration/json/test.php M tests/runtests.sh 7 files changed, 89 insertions(+), 1 deletion(-) diff --git a/README b/README index 42bf034..128b2fd 100644 --- a/README +++ b/README @@ -9,3 +9,8 @@ project or a MediaWiki/MediaWiki extension respectively. This is only tested with Phan 0.8.0 + +== Environment variables == +The following environment variables affect the plugin: +* SECURITY_CHECK_EXT_PATH - Path to extension.json when in MediaWiki mode. If not set assumes the project root directory. +* SECCHECK_DEBUG - File to output extra debug information (If running from shell, /dev/stderr is convenient) diff --git a/src/MediaWikiSecurityCheckPlugin.php b/src/MediaWikiSecurityCheckPlugin.php index bc66349..7bcee97 100644 --- a/src/MediaWikiSecurityCheckPlugin.php +++ b/src/MediaWikiSecurityCheckPlugin.php @@ -7,9 +7,12 @@ require_once __DIR__ . "/MWPreVisitor.php"; use Phan\CodeBase; +use Phan\Config; use Phan\Language\Context; use Phan\Language\FQSEN\FullyQualifiedFunctionLikeName; use Phan\Language\FQSEN\FullyQualifiedClassName; +use Phan\Language\FQSEN\FullyQualifiedFunctionName as FQSENFunc; +use Phan\Language\FQSEN\FullyQualifiedMethodName as FQSENMethod; use ast\Node; class MediaWikiSecurityCheckPlugin extends SecurityCheckPlugin { @@ -284,12 +287,56 @@ } /** +* Register hooks from extension.json +* +* Assumes extension.json is in project root directory +* unless SECURITY_CHECK_EXT_PATH is set +*/ + protected function loadExtensionJson() { + static $done; + if ( $done ) { + return; + } + $done = true; + $envPath = getenv( 'SECURITY_CHECK_EXT_PATH' ); + if ( $envPath ) { + $jsonPath = $envPath . '/' . 'extension.json'; + } else { + $jsonPath = Config::projectPath( 'extension.json' ); + } + if ( file_exists( $jsonPath ) ) { + $json = json_decode( file_get_contents( $jsonPath ), true ); + if ( !is_array( $json ) ) { + return; + } + if ( isset( $json['Hooks'] ) && is_array( $json['Hooks'] ) ) { + foreach ( $json['Hooks'] as $hookName => $cbList ) { + foreach ( (array)$cbList as $cb ) { + // All callbacks here are simple + // "someFunction" or "Class::SomeMethod" + if ( strpos( $cb, '::' ) === false ) { + $callback = FQSENFunc::fromFullyQualifiedString( + $cb + ); + } else { + $callback = FQSENMethod::fromFullyQualifiedString( + $cb + ); + } + $this->registerHook( $hookName, $callback ); + } + } + } + } + } + /** * Get a list of subscribers for hook * * @param string $hookName Hook in question. Hooks starting with ! are special. * @return FullyQualifiedFunctionLikeName[] */ public function getHookSubscribers( string $hookName ) : array { + $this->loadExtensionJson(); if ( isset( $this->hookSubscribers[$hookName] ) ) { return $this->hookSubscribers[$hookName]; } @@ -305,6 +352,7 @@ * @return string The hook it is implementing */ public function isSpecialHookSubscriber( FullyQualifiedFunctionLikeName $fqsen ) { + $this->loadExtensionJson(); $specialHooks = [ '!ParserFunctionHook', '!ParserHook' diff --git a/tests/integration/json/Parser.php
[MediaWiki-commits] [Gerrit] mediawiki...SecurityCheckPlugin[master]: Support loading hook information from extension.json
Brian Wolff has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/394092 ) Change subject: Support loading hook information from extension.json .. Support loading hook information from extension.json As of yet, nothing is done with hook info. Change-Id: I978302f5a6f18ab2070af4e296cdcd20faaa4a07 --- M README M src/MediaWikiSecurityCheckPlugin.php A tests/integration/json/Parser.php A tests/integration/json/expectedResults.txt A tests/integration/json/extension.json A tests/integration/json/test.php M tests/runtests.sh 7 files changed, 89 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/tools/phan/SecurityCheckPlugin refs/changes/92/394092/1 diff --git a/README b/README index 42bf034..128b2fd 100644 --- a/README +++ b/README @@ -9,3 +9,8 @@ project or a MediaWiki/MediaWiki extension respectively. This is only tested with Phan 0.8.0 + +== Environment variables == +The following environment variables affect the plugin: +* SECURITY_CHECK_EXT_PATH - Path to extension.json when in MediaWiki mode. If not set assumes the project root directory. +* SECCHECK_DEBUG - File to output extra debug information (If running from shell, /dev/stderr is convenient) diff --git a/src/MediaWikiSecurityCheckPlugin.php b/src/MediaWikiSecurityCheckPlugin.php index bc66349..7bcee97 100644 --- a/src/MediaWikiSecurityCheckPlugin.php +++ b/src/MediaWikiSecurityCheckPlugin.php @@ -7,9 +7,12 @@ require_once __DIR__ . "/MWPreVisitor.php"; use Phan\CodeBase; +use Phan\Config; use Phan\Language\Context; use Phan\Language\FQSEN\FullyQualifiedFunctionLikeName; use Phan\Language\FQSEN\FullyQualifiedClassName; +use Phan\Language\FQSEN\FullyQualifiedFunctionName as FQSENFunc; +use Phan\Language\FQSEN\FullyQualifiedMethodName as FQSENMethod; use ast\Node; class MediaWikiSecurityCheckPlugin extends SecurityCheckPlugin { @@ -284,12 +287,56 @@ } /** +* Register hooks from extension.json +* +* Assumes extension.json is in project root directory +* unless SECURITY_CHECK_EXT_PATH is set +*/ + protected function loadExtensionJson() { + static $done; + if ( $done ) { + return; + } + $done = true; + $envPath = getenv( 'SECURITY_CHECK_EXT_PATH' ); + if ( $envPath ) { + $jsonPath = $envPath . '/' . 'extension.json'; + } else { + $jsonPath = Config::projectPath( 'extension.json' ); + } + if ( file_exists( $jsonPath ) ) { + $json = json_decode( file_get_contents( $jsonPath ), true ); + if ( !is_array( $json ) ) { + return; + } + if ( isset( $json['Hooks'] ) && is_array( $json['Hooks'] ) ) { + foreach ( $json['Hooks'] as $hookName => $cbList ) { + foreach ( (array)$cbList as $cb ) { + // All callbacks here are simple + // "someFunction" or "Class::SomeMethod" + if ( strpos( $cb, '::' ) === false ) { + $callback = FQSENFunc::fromFullyQualifiedString( + $cb + ); + } else { + $callback = FQSENMethod::fromFullyQualifiedString( + $cb + ); + } + $this->registerHook( $hookName, $callback ); + } + } + } + } + } + /** * Get a list of subscribers for hook * * @param string $hookName Hook in question. Hooks starting with ! are special. * @return FullyQualifiedFunctionLikeName[] */ public function getHookSubscribers( string $hookName ) : array { + $this->loadExtensionJson(); if ( isset( $this->hookSubscribers[$hookName] ) ) { return $this->hookSubscribers[$hookName]; } @@ -305,6 +352,7 @@ * @return string The hook it is implementing */ public function isSpecialHookSubscriber( FullyQualifiedFunctionLikeName $fqsen ) { + $this->loadExtensionJson(); $specialHooks = [