From d3252c31762b4cbf78a5270206be832489f7e13d Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Mon, 2 Dec 2019 09:39:03 -0500 Subject: [PATCH] ApiEditPage: Test for bad redirect targets Apparently everything downstream assumes callers already handled interwiki titles. See also T239466 for related code-hardening. Bug: T239428 Change-Id: Ie54f366986056c876eade0fcad6c41f70b8b8de8 (cherry picked from commit 9084591e104fc10f004044f552b47ad27e7d763b) --- includes/api/ApiEditPage.php | 16 +++++++++++++++- includes/api/i18n/en.json | 1 + includes/api/i18n/qqq.json | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php index 1936407ac3..c5fe9c8cdd 100644 --- a/includes/api/ApiEditPage.php +++ b/includes/api/ApiEditPage.php @@ -63,7 +63,7 @@ class ApiEditPage extends ApiBase { /** @var Title $newTitle */ foreach ( $titles as $id => $newTitle ) { - $titles[ $id - 1 ] = $titles[ $id - 1 ] ?? $oldTitle; + $titles[$id - 1] = $titles[$id - 1] ?? $oldTitle; $redirValues[] = [ 'from' => $titles[$id - 1]->getPrefixedText(), @@ -71,6 +71,20 @@ class ApiEditPage extends ApiBase { ]; $titleObj = $newTitle; + + // T239428: Check whether the new title is valid + if ( $titleObj->isExternal() || !$titleObj->canExist() ) { + $redirValues[count( $redirValues ) - 1]['to'] = $titleObj->getFullText(); + $this->dieWithError( + [ + 'apierror-edit-invalidredirect', + Message::plaintextParam( $oldTitle->getPrefixedText() ), + Message::plaintextParam( $titleObj->getFullText() ), + ], + 'edit-invalidredirect', + [ 'redirects' => $redirValues ] + ); + } } ApiResult::setIndexedTagName( $redirValues, 'r' ); diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index cc5e872cee..c0884504b8 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -1751,6 +1751,7 @@ "apierror-csp-report": "Error processing CSP report: $1.", "apierror-deletedrevs-param-not-1-2": "The $1 parameter cannot be used in modes 1 or 2.", "apierror-deletedrevs-param-not-3": "The $1 parameter cannot be used in mode 3.", + "apierror-edit-invalidredirect": "Cannot edit $1 while following redirects, as target $2 is not valid.", "apierror-emptynewsection": "Creating empty new sections is not possible.", "apierror-emptypage": "Creating new, empty pages is not allowed.", "apierror-exceptioncaught": "[$1] Exception caught: $2", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index 25e7522f66..ed97f79cc9 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -1639,6 +1639,7 @@ "apierror-csp-report": "{{doc-apierror}}\n\nParameters:\n* $1 - Error code, e.g. \"toobig\".", "apierror-deletedrevs-param-not-1-2": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}", "apierror-deletedrevs-param-not-3": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}", + "apierror-edit-invalidredirect": "{{doc-apierror}}\n\nParameters:\n* $1 - Redirect being edited\n* $2 - Target of the redirect that cannot be edited.", "apierror-emptynewsection": "{{doc-apierror}}", "apierror-emptypage": "{{doc-apierror}}", "apierror-exceptioncaught": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.\n* $2 - Exception message, which may end with punctuation. Probably in English.", -- 2.20.1