wikimedia /
mediawiki
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Tools for dealing with other locally-hosted wikis. |
||
| 4 | * |
||
| 5 | * This program is free software; you can redistribute it and/or modify |
||
| 6 | * it under the terms of the GNU General Public License as published by |
||
| 7 | * the Free Software Foundation; either version 2 of the License, or |
||
| 8 | * (at your option) any later version. |
||
| 9 | * |
||
| 10 | * This program is distributed in the hope that it will be useful, |
||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 13 | * GNU General Public License for more details. |
||
| 14 | * |
||
| 15 | * You should have received a copy of the GNU General Public License along |
||
| 16 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
| 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
| 18 | * http://www.gnu.org/copyleft/gpl.html |
||
| 19 | * |
||
| 20 | * @file |
||
| 21 | */ |
||
| 22 | |||
| 23 | /** |
||
| 24 | * Helper tools for dealing with other wikis. |
||
| 25 | */ |
||
| 26 | class WikiMap { |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Get a WikiReference object for $wikiID |
||
| 30 | * |
||
| 31 | * @param string $wikiID Wiki'd id (generally database name) |
||
| 32 | * @return WikiReference|null WikiReference object or null if the wiki was not found |
||
| 33 | */ |
||
| 34 | public static function getWiki( $wikiID ) { |
||
| 35 | $wikiReference = self::getWikiReferenceFromWgConf( $wikiID ); |
||
| 36 | if ( $wikiReference ) { |
||
| 37 | return $wikiReference; |
||
| 38 | } |
||
| 39 | |||
| 40 | // Try sites, if $wgConf failed |
||
| 41 | return self::getWikiWikiReferenceFromSites( $wikiID ); |
||
| 42 | } |
||
| 43 | |||
| 44 | /** |
||
| 45 | * @param string $wikiID |
||
| 46 | * @return WikiReference|null WikiReference object or null if the wiki was not found |
||
| 47 | */ |
||
| 48 | private static function getWikiReferenceFromWgConf( $wikiID ) { |
||
| 49 | global $wgConf; |
||
| 50 | |||
| 51 | $wgConf->loadFullData(); |
||
| 52 | |||
| 53 | list( $major, $minor ) = $wgConf->siteFromDB( $wikiID ); |
||
| 54 | if ( $major === null ) { |
||
| 55 | return null; |
||
| 56 | } |
||
| 57 | $server = $wgConf->get( 'wgServer', $wikiID, $major, |
||
| 58 | [ 'lang' => $minor, 'site' => $major ] ); |
||
| 59 | |||
| 60 | $canonicalServer = $wgConf->get( 'wgCanonicalServer', $wikiID, $major, |
||
| 61 | [ 'lang' => $minor, 'site' => $major ] ); |
||
| 62 | if ( $canonicalServer === false || $canonicalServer === null ) { |
||
| 63 | $canonicalServer = $server; |
||
| 64 | } |
||
| 65 | |||
| 66 | $path = $wgConf->get( 'wgArticlePath', $wikiID, $major, |
||
| 67 | [ 'lang' => $minor, 'site' => $major ] ); |
||
| 68 | |||
| 69 | // If we don't have a canonical server or a path containing $1, the |
||
| 70 | // WikiReference isn't going to function properly. Just return null in |
||
| 71 | // that case. |
||
| 72 | if ( !is_string( $canonicalServer ) || !is_string( $path ) || strpos( $path, '$1' ) === false ) { |
||
| 73 | return null; |
||
| 74 | } |
||
| 75 | |||
| 76 | return new WikiReference( $canonicalServer, $path, $server ); |
||
| 77 | } |
||
| 78 | |||
| 79 | /** |
||
| 80 | * @param string $wikiID |
||
| 81 | * @return WikiReference|null WikiReference object or null if the wiki was not found |
||
| 82 | */ |
||
| 83 | private static function getWikiWikiReferenceFromSites( $wikiID ) { |
||
| 84 | $siteLookup = \MediaWiki\MediaWikiServices::getInstance()->getSiteLookup(); |
||
| 85 | $site = $siteLookup->getSite( $wikiID ); |
||
| 86 | |||
| 87 | if ( !$site instanceof MediaWikiSite ) { |
||
| 88 | // Abort if not a MediaWikiSite, as this is about Wikis |
||
| 89 | return null; |
||
| 90 | } |
||
| 91 | |||
| 92 | $urlParts = wfParseUrl( $site->getPageUrl() ); |
||
| 93 | if ( $urlParts === false || !isset( $urlParts['path'] ) || !isset( $urlParts['host'] ) ) { |
||
| 94 | // We can't create a meaningful WikiReference without URLs |
||
| 95 | return null; |
||
| 96 | } |
||
| 97 | |||
| 98 | // XXX: Check whether path contains a $1? |
||
| 99 | $path = $urlParts['path']; |
||
| 100 | if ( isset( $urlParts['query'] ) ) { |
||
| 101 | $path .= '?' . $urlParts['query']; |
||
| 102 | } |
||
| 103 | |||
| 104 | $canonicalServer = isset( $urlParts['scheme'] ) ? $urlParts['scheme'] : 'http'; |
||
| 105 | $canonicalServer .= '://' . $urlParts['host']; |
||
| 106 | |||
| 107 | return new WikiReference( $canonicalServer, $path ); |
||
| 108 | } |
||
| 109 | |||
| 110 | /** |
||
| 111 | * Convenience to get the wiki's display name |
||
| 112 | * |
||
| 113 | * @todo We can give more info than just the wiki id! |
||
| 114 | * @param string $wikiID Wiki'd id (generally database name) |
||
| 115 | * @return string|int Wiki's name or $wiki_id if the wiki was not found |
||
| 116 | */ |
||
| 117 | public static function getWikiName( $wikiID ) { |
||
| 118 | $wiki = WikiMap::getWiki( $wikiID ); |
||
| 119 | |||
| 120 | if ( $wiki ) { |
||
| 121 | return $wiki->getDisplayName(); |
||
| 122 | } |
||
| 123 | return $wikiID; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Convenience to get a link to a user page on a foreign wiki |
||
| 128 | * |
||
| 129 | * @param string $wikiID Wiki'd id (generally database name) |
||
| 130 | * @param string $user User name (must be normalised before calling this function!) |
||
| 131 | * @param string $text Link's text; optional, default to "User:$user" |
||
| 132 | * @return string HTML link or false if the wiki was not found |
||
| 133 | */ |
||
| 134 | public static function foreignUserLink( $wikiID, $user, $text = null ) { |
||
| 135 | return self::makeForeignLink( $wikiID, "User:$user", $text ); |
||
| 136 | } |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Convenience to get a link to a page on a foreign wiki |
||
| 140 | * |
||
| 141 | * @param string $wikiID Wiki'd id (generally database name) |
||
| 142 | * @param string $page Page name (must be normalised before calling this function!) |
||
| 143 | * @param string $text Link's text; optional, default to $page |
||
| 144 | * @return string HTML link or false if the wiki was not found |
||
| 145 | */ |
||
| 146 | public static function makeForeignLink( $wikiID, $page, $text = null ) { |
||
| 147 | if ( !$text ) { |
||
|
0 ignored issues
–
show
|
|||
| 148 | $text = $page; |
||
| 149 | } |
||
| 150 | |||
| 151 | $url = self::getForeignURL( $wikiID, $page ); |
||
| 152 | if ( $url === false ) { |
||
| 153 | return false; |
||
| 154 | } |
||
| 155 | |||
| 156 | return Linker::makeExternalLink( $url, $text ); |
||
| 157 | } |
||
| 158 | |||
| 159 | /** |
||
| 160 | * Convenience to get a url to a page on a foreign wiki |
||
| 161 | * |
||
| 162 | * @param string $wikiID Wiki'd id (generally database name) |
||
| 163 | * @param string $page Page name (must be normalised before calling this function!) |
||
| 164 | * @param string|null $fragmentId |
||
| 165 | * |
||
| 166 | * @return string|bool URL or false if the wiki was not found |
||
| 167 | */ |
||
| 168 | public static function getForeignURL( $wikiID, $page, $fragmentId = null ) { |
||
| 169 | $wiki = WikiMap::getWiki( $wikiID ); |
||
| 170 | |||
| 171 | if ( $wiki ) { |
||
| 172 | return $wiki->getFullUrl( $page, $fragmentId ); |
||
| 173 | } |
||
| 174 | |||
| 175 | return false; |
||
| 176 | } |
||
| 177 | } |
||
| 178 | |||
| 179 | /** |
||
| 180 | * Reference to a locally-hosted wiki |
||
| 181 | */ |
||
| 182 | class WikiReference { |
||
| 183 | private $mCanonicalServer; ///< canonical server URL, e.g. 'https://www.mediawiki.org' |
||
| 184 | private $mServer; ///< server URL, may be protocol-relative, e.g. '//www.mediawiki.org' |
||
| 185 | private $mPath; ///< path, '/wiki/$1' |
||
| 186 | |||
| 187 | /** |
||
| 188 | * @param string $canonicalServer |
||
| 189 | * @param string $path |
||
| 190 | * @param null|string $server |
||
| 191 | */ |
||
| 192 | public function __construct( $canonicalServer, $path, $server = null ) { |
||
| 193 | $this->mCanonicalServer = $canonicalServer; |
||
| 194 | $this->mPath = $path; |
||
| 195 | $this->mServer = $server === null ? $canonicalServer : $server; |
||
| 196 | } |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Get the URL in a way to be displayed to the user |
||
| 200 | * More or less Wikimedia specific |
||
| 201 | * |
||
| 202 | * @return string |
||
| 203 | */ |
||
| 204 | public function getDisplayName() { |
||
| 205 | $parsed = wfParseUrl( $this->mCanonicalServer ); |
||
| 206 | if ( $parsed ) { |
||
| 207 | return $parsed['host']; |
||
| 208 | } else { |
||
| 209 | // Invalid server spec. |
||
| 210 | // There's no sane thing to do here, so just return the canonical server name in full. |
||
| 211 | return $this->mCanonicalServer; |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | /** |
||
| 216 | * Helper function for getUrl() |
||
| 217 | * |
||
| 218 | * @todo FIXME: This may be generalized... |
||
| 219 | * |
||
| 220 | * @param string $page Page name (must be normalised before calling this function! |
||
| 221 | * May contain a section part.) |
||
| 222 | * @param string|null $fragmentId |
||
| 223 | * |
||
| 224 | * @return string relative URL, without the server part. |
||
| 225 | */ |
||
| 226 | private function getLocalUrl( $page, $fragmentId = null ) { |
||
| 227 | $page = wfUrlencode( str_replace( ' ', '_', $page ) ); |
||
| 228 | |||
| 229 | if ( is_string( $fragmentId ) && $fragmentId !== '' ) { |
||
| 230 | $page .= '#' . wfUrlencode( $fragmentId ); |
||
| 231 | } |
||
| 232 | |||
| 233 | return str_replace( '$1', $page, $this->mPath ); |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * Get a canonical (i.e. based on $wgCanonicalServer) URL to a page on this foreign wiki |
||
| 238 | * |
||
| 239 | * @param string $page Page name (must be normalised before calling this function!) |
||
| 240 | * @param string|null $fragmentId |
||
| 241 | * |
||
| 242 | * @return string Url |
||
| 243 | */ |
||
| 244 | public function getCanonicalUrl( $page, $fragmentId = null ) { |
||
| 245 | return $this->mCanonicalServer . $this->getLocalUrl( $page, $fragmentId ); |
||
| 246 | } |
||
| 247 | |||
| 248 | /** |
||
| 249 | * Get a canonical server URL |
||
| 250 | * @return string |
||
| 251 | */ |
||
| 252 | public function getCanonicalServer() { |
||
| 253 | return $this->mCanonicalServer; |
||
| 254 | } |
||
| 255 | |||
| 256 | /** |
||
| 257 | * Alias for getCanonicalUrl(), for backwards compatibility. |
||
| 258 | * @param string $page |
||
| 259 | * @param string|null $fragmentId |
||
| 260 | * |
||
| 261 | * @return string |
||
| 262 | */ |
||
| 263 | public function getUrl( $page, $fragmentId = null ) { |
||
| 264 | return $this->getCanonicalUrl( $page, $fragmentId ); |
||
| 265 | } |
||
| 266 | |||
| 267 | /** |
||
| 268 | * Get a URL based on $wgServer, like Title::getFullURL() would produce |
||
| 269 | * when called locally on the wiki. |
||
| 270 | * |
||
| 271 | * @param string $page Page name (must be normalized before calling this function!) |
||
| 272 | * @param string|null $fragmentId |
||
| 273 | * |
||
| 274 | * @return string URL |
||
| 275 | */ |
||
| 276 | public function getFullUrl( $page, $fragmentId = null ) { |
||
| 277 | return $this->mServer . |
||
| 278 | $this->getLocalUrl( $page, $fragmentId ); |
||
| 279 | } |
||
| 280 | } |
||
| 281 |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: