From 61b863f17c1e4fc9a56ec22ac690894027841d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Mart=C3=ADnez=20Novo?= Date: Wed, 20 Dec 2023 22:54:28 +0100 Subject: [PATCH 1/2] Fix missing break statement after empty condition When grabNewText doesn't find anything new, it was erroring out because execution was continuing on an empty array instead of breaking the loop Change-Id: I52cad6ec4c253cc9428921536366e60cb253bc20 --- grabNewText.php | 1 + 1 file changed, 1 insertion(+) diff --git a/grabNewText.php b/grabNewText.php index 0eabe60..d64aabe 100644 --- a/grabNewText.php +++ b/grabNewText.php @@ -143,6 +143,7 @@ function processRecentChanges() { $result = $this->bot->query( $params ); if ( empty( $result['query']['recentchanges'] ) ) { $this->output( 'No changes found...' ); + break; } foreach ( $result['query']['recentchanges'] as $entry ) { # new pages, new uploads, edited pages From f2280ac6309be6d7cbb3d2de93008596580db77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Mart=C3=ADnez=20Novo?= Date: Sun, 21 Jan 2024 19:43:17 +0100 Subject: [PATCH 2/2] Check for invalid user names with id Detected rare cases of user names not properly canonicalized on external wikis, which cause issues when the user gets inserted on the database by the ActorStore class, and the rename detection logic finds the user being renamed when it wasn't. Those cases should be very rare, from old accounts. To avoid such problems, they'll be transformed into imported users with no local user. Check also for valid user names with no user id and not using the external user name syntax, convert them to imported too, because the actor logic is trying to normalize them and sometimes they cause errors which abort the process. Bug: T353766 Bug: T353767 Change-Id: I699c1bd53256a9fc8544d30b981392e4c68a9323 --- includes/ExternalWikiGrabber.php | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/includes/ExternalWikiGrabber.php b/includes/ExternalWikiGrabber.php index 3a236ec..5af497b 100644 --- a/includes/ExternalWikiGrabber.php +++ b/includes/ExternalWikiGrabber.php @@ -7,7 +7,7 @@ * @author Jack Phoenix * @author Calimonious the Estrange * @author Jesús Martínez - * @date 5 November 2023 + * @date 21 January 2024 * @version 1.1 */ @@ -145,11 +145,21 @@ function getUserIdentity( $id, $name ) { return $this->actorStore->getUnknownActor(); } - # Old imported revisions might be assigned to anon users. - # We also need to prefix system users if they really have no user ID - # on the remote site, so we are not using ::isUsable() as ActorStore do. - if ( !$id && $this->userNameUtils->isValid( $name ) ) { - $name = 'imported>' . $name; + if ( !$id and !$this->userNameUtils->isIP( $name ) and !ExternalUserNames::isExternal( $name ) ) { + # Everything that's not an IP or external, must be converted to external + # Old imported revisions might be assigned to anon users. + # We also need to prefix system users if they really have no user ID + $name = "imported>$name"; + } elseif ( $id and !$this->userNameUtils->isValid( $name ) ) { + # T353766: There's an edge case of apparently valid but not canonicalized usernames. + # For example, usernames which start with lowercase characters. + # Those users cause problems when this script detects a user name change, + # because ActorStore does a normalization when inserting, but the external wiki + # may have old users that don't follow current canonicalization rules. + # Users with non-canonicalized names will be reported as invalid, and despite having + # user id on the external wiki, they'll be inserted as imported to avoid further errors + $name = "imported>$name"; + $id = 0; } elseif ( $id ) { $name = $this->userMappings[$id] ?? $name; $userIdentity = $this->actorStore->getUserIdentityByUserId( $id ); @@ -157,7 +167,7 @@ function getUserIdentity( $id, $name ) { $oldname = $userIdentity->getName(); # Cache the new user name for uncompleted user rename. $this->userMappings[$id] = $name = $this->getAndUpdateUserName( $userIdentity ); - $this->output( "Notice: We encountered an user rename on ID $id, $oldname => $name\n" ); + $this->output( "Notice: We encountered a user rename on ID $id, $oldname => $name\n" ); } elseif ( $userIdentity ) { return $userIdentity; }