X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fapi%2FApiMain.php;h=646823573d296d1aebe086aa740ca174ec2fdb39;hp=d7586e082281e9fb052ef78e293ee827e5b778b2;hb=1e8f417f3d6d648e19c03465890b58a331514362;hpb=8ddf721b6feaf11c67aafc1445d255e68faa4007 diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index d7586e0822..646823573d 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -581,23 +581,12 @@ class ApiMain extends ApiBase { // T65145: Rollback any open database transactions if ( !( $e instanceof ApiUsageException || $e instanceof UsageException ) ) { // UsageExceptions are intentional, so don't rollback if that's the case - try { - MWExceptionHandler::rollbackMasterChangesAndLog( $e ); - } catch ( DBError $e2 ) { - // Rollback threw an exception too. Log it, but don't interrupt - // our regularly scheduled exception handling. - MWExceptionHandler::logException( $e2 ); - } + MWExceptionHandler::rollbackMasterChangesAndLog( $e ); } // Allow extra cleanup and logging Hooks::run( 'ApiMain::onException', [ $this, $e ] ); - // Log it - if ( !( $e instanceof ApiUsageException || $e instanceof UsageException ) ) { - MWExceptionHandler::logException( $e ); - } - // Handle any kind of exception by outputting properly formatted error message. // If this fails, an unhandled exception should be thrown so that global error // handler will process and log it. @@ -704,13 +693,17 @@ class ApiMain extends ApiBase { $request = $this->getRequest(); $response = $request->response(); - $matchOrigin = false; + $matchedOrigin = false; $allowTiming = false; $varyOrigin = true; if ( $originParam === '*' ) { // Request for anonymous CORS - $matchOrigin = true; + // Technically we should check for the presence of an Origin header + // and not process it as CORS if it's not set, but that would + // require us to vary on Origin for all 'origin=*' requests which + // we don't want to do. + $matchedOrigin = true; $allowOrigin = '*'; $allowCredentials = 'false'; $varyOrigin = false; // No need to vary @@ -737,7 +730,7 @@ class ApiMain extends ApiBase { } $config = $this->getConfig(); - $matchOrigin = count( $origins ) === 1 && self::matchOrigin( + $matchedOrigin = count( $origins ) === 1 && self::matchOrigin( $originParam, $config->get( 'CrossSiteAJAXdomains' ), $config->get( 'CrossSiteAJAXdomainExceptions' ) @@ -748,19 +741,21 @@ class ApiMain extends ApiBase { $allowTiming = $originHeader; } - if ( $matchOrigin ) { + if ( $matchedOrigin ) { $requestedMethod = $request->getHeader( 'Access-Control-Request-Method' ); $preflight = $request->getMethod() === 'OPTIONS' && $requestedMethod !== false; if ( $preflight ) { // This is a CORS preflight request if ( $requestedMethod !== 'POST' && $requestedMethod !== 'GET' ) { // If method is not a case-sensitive match, do not set any additional headers and terminate. + $response->header( 'MediaWiki-CORS-Rejection: Unsupported method requested in preflight' ); return true; } // We allow the actual request to send the following headers $requestedHeaders = $request->getHeader( 'Access-Control-Request-Headers' ); if ( $requestedHeaders !== false ) { if ( !self::matchRequestedHeaders( $requestedHeaders ) ) { + $response->header( 'MediaWiki-CORS-Rejection: Unsupported header requested in preflight' ); return true; } $response->header( 'Access-Control-Allow-Headers: ' . $requestedHeaders ); @@ -768,6 +763,12 @@ class ApiMain extends ApiBase { // We only allow the actual request to be GET or POST $response->header( 'Access-Control-Allow-Methods: POST, GET' ); + } elseif ( $request->getMethod() !== 'POST' && $request->getMethod() !== 'GET' ) { + // Unsupported non-preflight method, don't handle it as CORS + $response->header( + 'MediaWiki-CORS-Rejection: Unsupported method for simple request or actual request' + ); + return true; } $response->header( "Access-Control-Allow-Origin: $allowOrigin" ); @@ -783,6 +784,8 @@ class ApiMain extends ApiBase { . 'MediaWiki-Login-Suppressed' ); } + } else { + $response->header( 'MediaWiki-CORS-Rejection: Origin mismatch' ); } if ( $varyOrigin ) { @@ -1038,7 +1041,7 @@ class ApiMain extends ApiBase { // None of the rest have any messages for non-error types } elseif ( $e instanceof UsageException ) { // User entered incorrect parameters - generate error response - $data = $e->getMessageArray(); + $data = MediaWiki\quietCall( [ $e, 'getMessageArray' ] ); $code = $data['code']; $info = $data['info']; unset( $data['code'], $data['info'] ); @@ -1826,7 +1829,7 @@ class ApiMain extends ApiBase { ApiBase::PARAM_TYPE => 'submodule', ], 'format' => [ - ApiBase::PARAM_DFLT => ApiMain::API_DEFAULT_FORMAT, + ApiBase::PARAM_DFLT => self::API_DEFAULT_FORMAT, ApiBase::PARAM_TYPE => 'submodule', ], 'maxlag' => [ @@ -1928,14 +1931,15 @@ class ApiMain extends ApiBase { $header = $this->msg( 'api-help-datatypes-header' )->parse(); - // Add an additional span with sanitized ID - if ( !$this->getConfig()->get( 'ExperimentalHtmlIds' ) ) { - $header = Html::element( 'span', [ 'id' => Sanitizer::escapeId( 'main/datatypes' ) ] ) . - $header; - } - $help['datatypes'] .= Html::rawElement( 'h' . min( 6, $level ), - [ 'id' => 'main/datatypes', 'class' => 'apihelp-header' ], - $header + $id = Sanitizer::escapeIdForAttribute( 'main/datatypes', Sanitizer::ID_PRIMARY ); + $idFallback = Sanitizer::escapeIdForAttribute( 'main/datatypes', Sanitizer::ID_FALLBACK ); + + $help['datatypes'] .= Linker::makeHeadline( min( 6, $level ), + ' class="apihelp-header"', + $id, + $header, + '', + $idFallback ); $help['datatypes'] .= $this->msg( 'api-help-datatypes' )->parseAsBlock(); if ( !isset( $tocData['main/datatypes'] ) ) { @@ -1950,15 +1954,15 @@ class ApiMain extends ApiBase { ]; } - // Add an additional span with sanitized ID - if ( !$this->getConfig()->get( 'ExperimentalHtmlIds' ) ) { - $header = Html::element( 'span', [ 'id' => Sanitizer::escapeId( 'main/credits' ) ] ) . - $header; - } $header = $this->msg( 'api-credits-header' )->parse(); - $help['credits'] .= Html::rawElement( 'h' . min( 6, $level ), - [ 'id' => 'main/credits', 'class' => 'apihelp-header' ], - $header + $id = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_PRIMARY ); + $idFallback = Sanitizer::escapeIdForAttribute( 'main/credits', Sanitizer::ID_FALLBACK ); + $help['credits'] .= Linker::makeHeadline( min( 6, $level ), + ' class="apihelp-header"', + $id, + $header, + '', + $idFallback ); $help['credits'] .= $this->msg( 'api-credits' )->useDatabase( false )->parseAsBlock(); if ( !isset( $tocData['main/credits'] ) ) {