X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/mediawiki.git/blobdiff_plain/74c929b24b048c9f1e31e17db757ae4195cd7673..HEAD:/includes/api/ApiFormatJson.php diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php index 1d89eb18..e5dafae6 100644 --- a/includes/api/ApiFormatJson.php +++ b/includes/api/ApiFormatJson.php @@ -1,11 +1,10 @@ @gmail.com + * Created on Sep 19, 2006 + * + * Copyright © 2006 Yuri Astrakhan "@gmail.com" * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,76 +18,121 @@ * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html + * + * @file */ -if (!defined('MEDIAWIKI')) { - // Eclipse helper - will be ignored in production - require_once ('ApiFormatBase.php'); -} - /** + * API JSON output formatter * @ingroup API */ class ApiFormatJson extends ApiFormatBase { - private $mIsRaw; + private $isRaw; + + public function __construct( ApiMain $main, $format ) { + parent::__construct( $main, $format ); + $this->isRaw = ( $format === 'rawfm' ); - public function __construct($main, $format) { - parent :: __construct($main, $format); - $this->mIsRaw = ($format === 'rawfm'); + if ( $this->getMain()->getCheck( 'callback' ) ) { + # T94015: jQuery appends a useless '_' parameter in jsonp mode. + # Mark the parameter as used in that case to avoid a warning that's + # outside the control of the end user. + # (and do it here because ApiMain::reportUnusedParams() gets called + # before our ::execute()) + $this->getMain()->markParamsUsed( '_' ); + } } public function getMimeType() { - return 'application/json'; - } + $params = $this->extractRequestParams(); + // callback: + if ( isset( $params['callback'] ) ) { + return 'text/javascript'; + } - public function getNeedsRawData() { - return $this->mIsRaw; + return 'application/json'; } public function execute() { - $prefix = $suffix = ""; - $params = $this->extractRequestParams(); - $callback = $params['callback']; - if(!is_null($callback)) { - $prefix = preg_replace("/[^][.\\'\\\"_A-Za-z0-9]/", "", $callback ) . "("; - $suffix = ")"; - } - // Some versions of PHP have a broken json_encode, see PHP bug - // 46944. Test encoding an affected character (U+20000) to - // avoid this. - if (!function_exists('json_encode') || $this->getIsHtml() || strtolower(json_encode("\xf0\xa0\x80\x80")) != '\ud840\udc00') { - $json = new Services_JSON(); - $this->printText($prefix . $json->encode($this->getResultData(), $this->getIsHtml()) . $suffix); + $opt = 0; + if ( $this->isRaw ) { + $opt |= FormatJson::ALL_OK; + $transform = []; } else { - $this->printText($prefix . json_encode($this->getResultData()) . $suffix); + switch ( $params['formatversion'] ) { + case 1: + $opt |= $params['utf8'] ? FormatJson::ALL_OK : FormatJson::XMLMETA_OK; + $transform = [ + 'BC' => [], + 'Types' => [ 'AssocAsObject' => true ], + 'Strip' => 'all', + ]; + break; + + case 2: + case 'latest': + $opt |= $params['ascii'] ? FormatJson::XMLMETA_OK : FormatJson::ALL_OK; + $transform = [ + 'Types' => [ 'AssocAsObject' => true ], + 'Strip' => 'all', + ]; + break; + + default: + // Should have been caught during parameter validation + $this->dieDebug( __METHOD__, 'Unknown value for \'formatversion\'' ); + } } - } + $data = $this->getResult()->getResultData( null, $transform ); + $json = FormatJson::encode( $data, $this->getIsHtml(), $opt ); - public function getAllowedParams() { - return array ( - 'callback' => null - ); - } + // T68776: wfMangleFlashPolicy() is needed to avoid a nasty bug in + // Flash, but what it does isn't friendly for the API, so we need to + // work around it. + if ( preg_match( '/\<\s*cross-domain-policy(?=\s|\>)/i', $json ) ) { + $json = preg_replace( + '/\<(\s*cross-domain-policy(?=\s|\>))/i', '\\u003C$1', $json + ); + } - public function getParamDescription() { - return array ( - 'callback' => 'If specified, wraps the output into a given function call. For safety, all user-specific data will be restricted.', - ); + if ( isset( $params['callback'] ) ) { + $callback = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", '', $params['callback'] ); + # Prepend a comment to try to avoid attacks against content + # sniffers, such as T70187. + $this->printText( "/**/$callback($json)" ); + } else { + $this->printText( $json ); + } } - public function getDescription() { - if ($this->mIsRaw) - return 'Output data with the debuging elements in JSON format' . parent :: getDescription(); - else - return 'Output data in JSON format' . parent :: getDescription(); - } + public function getAllowedParams() { + if ( $this->isRaw ) { + return parent::getAllowedParams(); + } - public function getVersion() { - return __CLASS__ . ': $Id: ApiFormatJson.php 45682 2009-01-12 19:06:33Z raymond $'; + $ret = parent::getAllowedParams() + [ + 'callback' => [ + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback', + ], + 'utf8' => [ + ApiBase::PARAM_DFLT => false, + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-utf8', + ], + 'ascii' => [ + ApiBase::PARAM_DFLT => false, + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-ascii', + ], + 'formatversion' => [ + ApiBase::PARAM_TYPE => [ 1, 2, 'latest' ], + ApiBase::PARAM_DFLT => 1, + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-formatversion', + ], + ]; + return $ret; } }