Page MenuHomePhabricator

User options supplied to client side empty due to json encoding errors (multibyte character cut in half)
Closed, ResolvedPublicBUG REPORT

Description

Developer notes

I've searched up mw.user.options.set in the page HTML and found one blank call mw.user.options.set(), yet the line has tokens in it and I'm better off not sharing it (line starts with (RLQ=window.RLQ||[])).

We may need to improve the validation of user options accordingly, to avoid invalid values being saved.

Original description

Steps to replicate the issue
I have no idea how to replicate this issue, it just broke without me changing anything, all scripts were working after my last change to any scripts.
Example links:

What happens?:
I have been consistently unable to use the 2017 wikitext editor and the IP info tool since yesterday (Jan 10), specifically on Chinese Wikipedia. The editor doesn't load at all, while the IP info tool consistently prompts me to accept the usage guidelines every time I open a new IP contribution special page. Before yesterday these tools worked without issue. I have tried to disable all user scripts (common.js) but had no luck recovering the beta features.

I find that the 2017 wikitext editor still works perfectly fine on all other Wikimedia sites, and only doesn't want to work on Chinese Wikipedia, though I haven't seen reports of other users facing the same issue. By comparing browser console logs, I find no specific warning message of loading failure but one warning message that might be related when loading the editor on Chinese Wikipedia:

ext.popups was loaded but everything is disabled

The same warning appears when I load up an IP contribution page. I'm not sure if this is likely what has broken both tools for me. If anyone can look into it and suggest what could have been wrong, and anything I can do client-wise to fix the issue. Thanks!

Edit (Jan 12):
Trying safemode=1 with both issues doesn't fix anything, issue also persists when using Desktop Mode on my mobile device, so it shouldn't be affected by extensions as I have none on my mobile.

Using debug=true on both 2017 editor and IP info pages give these new warning messages:

Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'interest-cohort'.
Error with Permissions-Policy header: Unrecognized origin: 'intake-analytics.wikimedia.org'.

What should have happened instead?: Normal loading and usage of beta features

Other information:

  • Cross-device issue, seems to not be a client problem
  • Browser: Microsoft Edge 108.0.1462.54 (Official build) for MacOS & Android
  • OS Version: MacOS Monterey (v12.1), MIUI Global 13.0.6 Stable

Event Timeline

Aklapper changed the task status from Open to Stalled.Jan 11 2023, 7:58 AM
Aklapper added a subscriber: Shizhao.

@LuciferianThomas: Thanks for reporting this. Please use the bug report form (linked from the top of the task creation page) to create a bug report, and fill in the sections in the template instead of deleting them, and always include full links. Thanks:

Clear steps to replicate the issue (include links if applicable):

What happens?:

What should have happened instead?:

Software version (skip for WMF-hosted wikis like Wikipedia):

Other information (browser name/version, screenshots, etc.):


Also, seeing https://zh.wikipedia.org/wiki/User:LuciferianThomas/common.js , please follow https://www.mediawiki.org/wiki/Help:Locating_broken_scripts

@Aklapper Thanks for the notification, edited the request. I can't really fill in any steps to reproduce the issue as I didn't do anything specific to break it, it was working as intended until some random time where I changed nothing.

Please always provide a full example URL where you see a problem, so others can also try to see something on the same page. Thanks! :)

@Aklapper Added, though I don't see the point when literally every single page edit action and IP contribution page is broken.

The editor doesn't load at all

I fail to reproduce with Firefox. :( Does this also happen when using another browser? Could you please post the complete output of the console tab in the browser's Developer Tools when going to https://zh.wikipedia.org/w/index.php?title=Wikipedia:沙盒&action=edit&safemode=1 ? Thanks!

[Intervention] Images loaded lazily and replaced with placeholders. Load events are deferred. See https://go.microsoft.com/fwlink/?linkid=2048113
load.php?lang=zh-hk&modules=ext.CodeMirror%2Ccharinsert%2CeventLogging%2CnavigationTiming%2Cpopups%2CwikimediaEvents%7Cext.CodeMirror.data%2Clib%7Cext.CodeMirror.mode.mediawiki%7Cext.centralNotice.geoIP%7Cext.centralauth.ForeignApi%7Cext.centralauth.centralautologin.clearcookie%7Cext.cx.eventlogging.campaigns%7Cext.discussionTools.init%7Cext.echo.api%2Cinit%7Cext.uls.common%2Ccompactlinks%2Cinterface%2Cpreferences%2Cwebfonts%7Cjquery%2Cmoment%2Coojs%2Coojs-ui-core%2Coojs-ui-windows%2Crangefix%7Cjquery.client%2Ccookie%2CtextSelection%2Cui%7Cjquery.uls.data%7Cmediawiki.ForeignApi%2CString%2CTitle%2CUri%2Capi%2Cbase%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cstorage%2Cuser%2Cutil%2CvisibleTimeout%7Cmediawiki.ForeignApi.core%7Cmediawiki.editfont.styles%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.page.ready%7Cmediawiki.page.watch.ajax%7Coojs-ui-core.icons%2Cstyles%7Coojs-ui-windows.icons%7Coojs-ui.styles.icons-editing-styling%2Cindicators%7Cskins.vector.es6%2Cjs%7Cskins.vector.icons.js&skin=vector-2022&version=1bj5z:1247 
        
       This page is using the deprecated ResourceLoader module "jquery.ui".
Please use OOUI instead.
mw.loader.implement.css @ load.php?lang=zh-hk&modules=ext.CodeMirror%2Ccharinsert%2CeventLogging%2CnavigationTiming%2Cpopups%2CwikimediaEvents%7Cext.CodeMirror.data%2Clib%7Cext.CodeMirror.mode.mediawiki%7Cext.centralNotice.geoIP%7Cext.centralauth.ForeignApi%7Cext.centralauth.centralautologin.clearcookie%7Cext.cx.eventlogging.campaigns%7Cext.discussionTools.init%7Cext.echo.api%2Cinit%7Cext.uls.common%2Ccompactlinks%2Cinterface%2Cpreferences%2Cwebfonts%7Cjquery%2Cmoment%2Coojs%2Coojs-ui-core%2Coojs-ui-windows%2Crangefix%7Cjquery.client%2Ccookie%2CtextSelection%2Cui%7Cjquery.uls.data%7Cmediawiki.ForeignApi%2CString%2CTitle%2CUri%2Capi%2Cbase%2Ccldr%2Ccookie%2Cexperiments%2CjqueryMsg%2Clanguage%2Cstorage%2Cuser%2Cutil%2CvisibleTimeout%7Cmediawiki.ForeignApi.core%7Cmediawiki.editfont.styles%7Cmediawiki.libs.pluralruleparser%7Cmediawiki.page.ready%7Cmediawiki.page.watch.ajax%7Coojs-ui-core.icons%2Cstyles%7Coojs-ui-windows.icons%7Coojs-ui.styles.icons-editing-styling%2Cindicators%7Cskins.vector.es6%2Cjs%7Cskins.vector.icons.js&skin=vector-2022&version=1bj5z:1247
load.php?lang=zh-hk&modules=ext.math.popup%7Cext.popups.icons%2Cimages%2Cmain%7Cmediawiki.ui.checkbox&skin=vector-2022&version=z2ila:46 
        
       ext.popups was loaded but everything is disabled
(anonymous) @ load.php?lang=zh-hk&modules=ext.math.popup%7Cext.popups.icons%2Cimages%2Cmain%7Cmediawiki.ui.checkbox&skin=vector-2022&version=z2ila:46

It also happens consistently with a second browser (Safari is tested in this case) and a second device (Edge mobile is also tested). No other Wikimedia site that I use are affected apart from the Chinese Wikipedia, i.e. I can edit with 2017 wikitext editor normally on other sites like zh.wikiversity and meta.wikimedia.

The log provided seems not helpful to me, but the description reminds me of T311799. You may try to follow the reproduce steps and my debug suggestion, and share more information here.

@Func I understand the part that my preferences are likely bricked somewhere - I guessed this is the most likely option given that the issue is across devices for me. However I do not particularly understand how to use the abovementioned task. I've searched up mw.user.options.set in the page HTML and found one blank call mw.user.options.set(), yet the line has tokens in it and I'm better off not sharing it (line starts with (RLQ=window.RLQ||[])).

Cool, blank call to mw.user.options.set(), that's interesting. I will try to investigate later today.

Func changed the task status from Stalled to Open.Jan 12 2023, 7:22 PM

Change 879085 had a related patch set uploaded (by Func; author: Func):

[mediawiki/core@master] UserOptionsModule: Log error when failed to encode user options

https://gerrit.wikimedia.org/r/879085

Func renamed this task from Unable to use multiple beta features on Chinese Wikipedia to User options supplied to the client side is empty due to json encoding errors.Jan 12 2023, 8:15 PM
Func updated the task description. (Show Details)

Hey there @Func, I noticed that my interwiki language menu has also been bricked in the same way as T326788. Is it possible that these issues could be inter-related?
Nevermind, I tried checking it while logged out and it seems like they aren't related, and it seems to happen consistently across zhwikipedia, reopened that task instead.

I feel like what broke all of the above would be the latest 1.40.0-wmf.18 version, since before that range of deployment dates I don't feel like there are any of such issues.

@Func is there a way for me to completely reset my preferences for zhwiki specifically so I can get out of the bricked situation? It's been annoying having 2017 editor broken.

You can save a copy of your current preferences via Special:ApiSandbox#action=query&format=json&meta=userinfo&formatversion=2&uiprop=options and check if there are any suspicious values.

If you can identify it, then you can reset only that option using API. Otherwise, you can use Special:Preferences#mw-input-wprestoreprefs to reset all preferences.

Aha, found the problem. I have visualeditor-findAndReplace-findText filled with a very long string (probably accidentally copy-pasted). Setting it to a blank string fixed things... I think.

Setting it to a blank string fixed things... I think.

So you are confirming that option bricked your preferences, or you have reset all preferences?

I didn't reset all preferences, the only thing I did reset was that specific preference string. I believe that is what caused my bricked preferences - failed to parse a (JSON) string type from the string-typed value when starting 2017 editor. I suppose it's normally saved like "visualeditor-findAndReplace-findText": "\\"[escaped content]\\"", but the latter escaped closing quotation mark was purged by overflowing the maximum length of preference strings I think? And such leaves me with "visualeditor-findAndReplace-findText": "\\"[very very long escaped content]" which is not a proper type and can't be parsed.

I reproduced this bug, the problem is how the database truncates the string. I saw a broken Unicode mark at the end of it when retrieving options from API, which means a Chinese character was truncated in half.

I don't think the truncated Chinese character is specifically the problem, I feel like it's more likely to be JS running JSON.parse on the preference value and resulting in an error.

Unpaired escaped quotes would not affect anything.
As you mentioned before, there is only a blank call to mw.user.options.set(), which means nothing to do with js on the client side, but failed to encode json in the backend.
API was designed to give an output when the error is not fatal, so it would normalize the string; while the resourceloader is strict on encoding json.

I've also encountered a similar issue a couple months ago, although for me the issue was less significant, since the parsing error was only occurring in VE: rEVED288159d65c69: Platform: Handle invalid JSON in the other path in #getUserConfig

Aklapper renamed this task from User options supplied to the client side is empty due to json encoding errors to User options supplied to client side empty due to json encoding errors (multibyte character cut in half).Jan 16 2023, 9:05 AM

Open questions:

  • The Options Action API appears to be accepting too-long values from clients (such as VisualEditor) and presumably responds with success desite having had to truncate the value.
  • The Options Action API, and possibly the underlying UserOptionsManager service class more generally, is truncating values such that they produce invalid Unicode. Most likely it's leaving it to the database layer where indeed it'd be cropped at the byte level, far too late in the process. We do have various faccilities already in-place for dealing with this, such as for edit summaries, user names, page titles, etc. I guess Language->truncate method isn't being used here?
  • VisualEditor perhaps could decide to proactively decline to try to store too-long values. However this would imho violate separations of concerns, and still be liable to regress long-term. If the feature is overall unlikely to fit most values then thats another matter, but on the face of it it seems fine to store as hidden user option. If it has no upper limit at all, I suppose it could have some very high limit like 1KB to avoid unbounded uploads that will be declined anyway, but it certainly doesnt need to match it exactly. The key thing is for it to tolerate cropped JSON strings on the consumer side, which I'm guessing it accounts for already, and is quite possibly the reason it quotes the string so that it can detect exactly this.

The last question is being explored at T327043, but imho orthogonal to this task and the first two questions.

Change 880527 had a related patch set uploaded (by Umherirrender; author: Umherirrender):

[mediawiki/core@master] user: Truncate option key/name in UserOptionsManager

https://gerrit.wikimedia.org/r/880527

Change 879085 abandoned by Func:

[mediawiki/core@master] ResourceLoader: Log error when json_encode in UserOptionsModule fails

Reason:

https://gerrit.wikimedia.org/r/879085

Change 881369 had a related patch set uploaded (by Func; author: Func):

[mediawiki/core@master] ApiOptions: Give warning if the value is too long

https://gerrit.wikimedia.org/r/881369

Change 880527 merged by jenkins-bot:

[mediawiki/core@master] user: Truncate option value in UserOptionsManager

https://gerrit.wikimedia.org/r/880527

Change 880527 merged by jenkins-bot:

[mediawiki/core@master] user: Truncate option value in UserOptionsManager

https://gerrit.wikimedia.org/r/880527

This does not fix broken preferences in the wild. It just avoid new broken preferences after deployment. But I would expect this as a low issue and not looking for broken preferences on the wikis. The next time the broken option is changed, it would fix itself.

The next time the broken option is changed, it would fix itself.

The main problem is when this happens with VE options, VE won't load at all, essentially bricking the options (options can only be changed when VE is loaded), leaving the API as the only way to fix things.

Change 881369 merged by jenkins-bot:

[mediawiki/core@master] ApiOptions: Give warning if the value is too long

https://gerrit.wikimedia.org/r/881369

Krinkle assigned this task to Umherirrender.
Krinkle moved this task from Limbo to Watching on the Performance-Team (Radar) board.

Change 884124 had a related patch set uploaded (by Func; author: Func):

[mediawiki/core@master] Replace some use of Language::truncateForDatabase() with mb_strcut()

https://gerrit.wikimedia.org/r/884124

Change 884124 merged by jenkins-bot:

[mediawiki/core@master] Replace some use of Language::truncateForDatabase() with mb_strcut()

https://gerrit.wikimedia.org/r/884124

Change 959024 had a related patch set uploaded (by Reedy; author: Func):

[mediawiki/core@REL1_39] ApiOptions: Give warning if the value is too long

https://gerrit.wikimedia.org/r/959024

Change 959274 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@master] Add since tag to UserOptionsManager::MAX_BYTES_OPTION_VALUE

https://gerrit.wikimedia.org/r/959274

Change 959288 had a related patch set uploaded (by Reedy; author: Umherirrender):

[mediawiki/core@REL1_39] user: Truncate option value in UserOptionsManager

https://gerrit.wikimedia.org/r/959288

Change 959288 merged by jenkins-bot:

[mediawiki/core@REL1_39] user: Truncate option value in UserOptionsManager

https://gerrit.wikimedia.org/r/959288

Change 959024 merged by jenkins-bot:

[mediawiki/core@REL1_39] ApiOptions: Give warning if the value is too long

https://gerrit.wikimedia.org/r/959024

Change 959274 merged by jenkins-bot:

[mediawiki/core@master] Add since tag to UserOptionsManager::MAX_BYTES_OPTION_VALUE

https://gerrit.wikimedia.org/r/959274

Change 959293 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@REL1_40] Add since tag to UserOptionsManager::MAX_BYTES_OPTION_VALUE

https://gerrit.wikimedia.org/r/959293

Change 959293 merged by jenkins-bot:

[mediawiki/core@REL1_40] Add since tag to UserOptionsManager::MAX_BYTES_OPTION_VALUE

https://gerrit.wikimedia.org/r/959293