user: Truncate option value in UserOptionsManager

To avoid truncation by the database,
which can result in broken utf-8 letters and would break on strict mode.

This is just the backend part. The api should validate and provide a
better message to the user instead of hard truncation without feedback

Bug: T326696
Change-Id: Id80c81956f78f87f4a97bd03f467a194d826fb42
This commit is contained in:
Umherirrender 2023-01-16 19:38:23 +01:00
parent 7ffcfc7610
commit 2a51865efe
3 changed files with 15 additions and 4 deletions

View file

@ -2124,7 +2124,8 @@ return [
$services->getDBLoadBalancer(),
LoggerFactory::getInstance( 'UserOptionsManager' ),
$services->getHookContainer(),
$services->getUserFactory()
$services->getUserFactory(),
$services->getContentLanguage()
);
},

View file

@ -26,6 +26,7 @@ use HTMLFormField;
use HTMLMultiSelectField;
use IContextSource;
use InvalidArgumentException;
use Language;
use LanguageCode;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\HookContainer\HookContainer;
@ -51,6 +52,8 @@ class UserOptionsManager extends UserOptionsLookup {
MainConfigNames::LocalTZoffset,
];
public const MAX_BYTES_OPTION_VALUE = 65530;
/** @var ServiceOptions */
private $serviceOptions;
@ -66,6 +69,9 @@ class UserOptionsManager extends UserOptionsLookup {
/** @var UserFactory */
private $userFactory;
/** @var Language */
private $contentLanguage;
/** @var LoggerInterface */
private $logger;
@ -99,6 +105,7 @@ class UserOptionsManager extends UserOptionsLookup {
* @param LoggerInterface $logger
* @param HookContainer $hookContainer
* @param UserFactory $userFactory
* @param Language $contentLanguage
*/
public function __construct(
ServiceOptions $options,
@ -107,7 +114,8 @@ class UserOptionsManager extends UserOptionsLookup {
ILoadBalancer $loadBalancer,
LoggerInterface $logger,
HookContainer $hookContainer,
UserFactory $userFactory
UserFactory $userFactory,
Language $contentLanguage
) {
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
$this->serviceOptions = $options;
@ -117,6 +125,7 @@ class UserOptionsManager extends UserOptionsLookup {
$this->logger = $logger;
$this->hookRunner = new HookRunner( $hookContainer );
$this->userFactory = $userFactory;
$this->contentLanguage = $contentLanguage;
}
/**
@ -440,7 +449,7 @@ class UserOptionsManager extends UserOptionsLookup {
$rowsToInsert[] = [
'up_user' => $user->getId(),
'up_property' => $key,
'up_value' => $value,
'up_value' => $this->contentLanguage->truncateForDatabase( $value, self::MAX_BYTES_OPTION_VALUE ),
];
if ( array_key_exists( $key, $this->optionsFromDb[$userKey] ) ) {
$keysToDelete[] = $key;

View file

@ -49,7 +49,8 @@ class UserOptionsManagerTest extends UserOptionsLookupTest {
$overrides['lb'] ?? $services->getDBLoadBalancer(),
new NullLogger(),
$overrides['hookContainer'] ?? $services->getHookContainer(),
$services->getUserFactory()
$services->getUserFactory(),
$services->getContentLanguage()
);
}