From 69f8ca9a7460093a68de0efa24100c7ee37037f1 Mon Sep 17 00:00:00 2001 From: Jakob Warkotsch Date: Wed, 18 Sep 2024 15:48:37 +0200 Subject: [PATCH] REST: Don't assume all non-Ok status contain messages I've encountered a case in which this was the case locally, and not assuming this array to be non-empty also makes the code a little more robust. Change-Id: Iaa006561961c378d8101d02c523fa3d446a7e13f --- .../DataAccess/EntityUpdater.php | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/repo/rest-api/src/Infrastructure/DataAccess/EntityUpdater.php b/repo/rest-api/src/Infrastructure/DataAccess/EntityUpdater.php index adc1abe94c..007f494216 100644 --- a/repo/rest-api/src/Infrastructure/DataAccess/EntityUpdater.php +++ b/repo/rest-api/src/Infrastructure/DataAccess/EntityUpdater.php @@ -7,6 +7,7 @@ use MediaWiki\Permissions\PermissionManager; use MediaWiki\Status\Status; use MediaWiki\User\User; +use MessageSpecifier; use Psr\Log\LoggerInterface; use RuntimeException; use Wikibase\DataModel\Entity\EntityDocument; @@ -98,8 +99,9 @@ private function createOrUpdate( ); if ( !$status->isOK() ) { - if ( $status->getMessages()[0]->getKey() === 'wikibase-error-entity-too-big' ) { - $maxSizeInKiloBytes = $status->getMessages()[0]->getParams()[0]['size'] / 1024; + $entityTooBigError = $this->findErrorInStatus( $status, 'wikibase-error-entity-too-big' ); + if ( $entityTooBigError ) { + $maxSizeInKiloBytes = $entityTooBigError->getParams()[0]['size'] / 1024; throw new ResourceTooLargeException( $maxSizeInKiloBytes ); } @@ -116,11 +118,20 @@ private function createOrUpdate( } private function isPreventedEdit( Status $status ): bool { - $errorCode = $status->getMessages()[0]->getKey(); + return $this->findErrorInStatus( $status, 'actionthrottledtext' ) + || $this->findErrorInStatus( $status, 'spam-blacklisted' ) + || $this->findErrorInStatus( $status, 'abusefilter' ); + } + + private function findErrorInStatus( Status $status, string $errorCode ): ?MessageSpecifier { + foreach ( $status->getMessages() as $message ) { + // prefix comparison to cover different kinds of spam-blacklisted or abusefilter errors + if ( strpos( $message->getKey(), $errorCode ) === 0 ) { + return $message; + } + } - return $errorCode === 'actionthrottledtext' - || strpos( $errorCode, 'spam-blacklisted' ) === 0 - || strpos( $errorCode, 'abusefilter' ) === 0; + return null; } private function checkBotRightIfProvided( User $user, bool $isBot ): void {