wordpress-mobile / wordpress-mobile/GutenbergKit
Editor settings fetch is gated behind theme styles, disabling upload validation
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29
- Forks
- 6
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
Description
Editor settings are only fetched when theme styles are enabled. Because allowedMimeTypes and maxUploadFileSize arrive in that same payload, turning theme styles off also silently disables the editor's client-side upload validation.
themeStyles should control whether theme CSS is applied, not whether settings are fetched.
Where
Both platforms short-circuit before the request:
ios/Sources/GutenbergKit/Sources/RESTAPIRepository.swift:93—if !self.configuration.shouldUseThemeStyles { return .undefined }android/Gutenberg/src/main/java/org/wordpress/gutenberg/RESTAPIRepository.kt:90—if (!configuration.themeStyles) return EditorSettings.undefined
Why it matters beyond styling
When EditorSettings.undefined is returned, jsonValue is nil, so GBKitGlobal passes nothing to the web layer (GBKitGlobal.swift:132, GBKitGlobal.kt:135). src/utils/editor.jsx:27 then falls back to getDefaultEditorSettings(), which sets no allowedMimeTypes — correctly, since it's a static styling floor and the value is site-specific.
The block-editor store default is allowedMimeTypes: null. In @wordpress/media-utils, validateMimeTypeForUser calls getMimeTypesArray(null), gets null, and returns early — every file type is accepted.
maxUploadFileSize fails the same way: it defaults to 0, and validateFileSize guards with if ( maxUploadFileSize && ... ), so the size limit is skipped too. Only the empty-file check survives.
The user-visible effect is that a file the server will reject gets uploaded anyway — after any client-side processing the host app performed (image re-encode, video transcode) — and the rejection arrives from the server instead.
Scope
This affects sites that have the settings endpoint, in three cases. In the WordPress iOS app, isThemeStylesEnabled is false when:
- the capability probe recorded "unsupported",
- the site was never probed (the lookup returns false for an absent entry, so an unprobed site reads as unsupported), or
- the user turned theme styles off in site settings.
Android reaches the same three via EditorCapabilityResolver.resolveThemeStyles.
Case 2 is worth calling out: a site that fully supports the endpoint can still skip the fetch simply because the probe hasn't run yet.
Step-by-step reproduction instructions
- Open a post in the GutenbergKit editor on a site running the Gutenberg plugin (so
/wp-block-editor/v1/settingsexists), with theme styles enabled. Confirmselect('core/block-editor').getSettings().allowedMimeTypesis populated. - Disable theme styles for that site in the host app's site settings.
- Reopen the editor.
allowedMimeTypesis nownullandmaxUploadFileSizeis0. - Insert a file the site disallows (e.g. a
.webmon a site whoseupload_mimesexcludes it). With theme styles on, the editor rejects it locally; with them off, it uploads and the server rejects it.
Proposed fix
Fetch editor settings independently of shouldUseThemeStyles / themeStyles, and keep that flag for deciding whether the returned themeStyles CSS is applied.
Related: EditorConfiguration.editorSettings is dead
Noticed while investigating; separable from the above, and worth a maintainer decision rather than a specific fix.
EditorConfiguration declares an editorSettings field on both platforms with a setEditorSettings builder:
ios/Sources/GutenbergKit/Sources/Model/EditorConfiguration.swift:49android/Gutenberg/src/main/java/org/wordpress/gutenberg/model/EditorConfiguration.kt:25
Nothing reads it. GBKitGlobal uses the fetched dependencies.editorSettings instead, so the configured value never reaches the editor. It is stored, copied through the builder, and folded into ==/hashCode — meaning an unread field can still make two otherwise-equal configurations compare unequal.
Two options:
- Delete it. Simplest, and removes the equality side effect.
- Wire it up as a host-supplied fallback when the fetch is skipped or the endpoint is absent.
We investigated the second option for the WordPress apps and are not currently pursuing it, for two reasons worth recording here:
- Little to supply.
/wp-block-editor/v1/settingsis provided by the Gutenberg plugin, not WordPress core — core computesallowedMimeTypesinget_block_editor_settings()but exposes no REST route for it. On a site without the plugin, we checked every REST alternative (/wp-json/root,/wp/v2/users/me?context=edit,OPTIONS /wp/v2/media,/wp/v2/settings) and none carries a MIME allowlist or upload limit. So for directly-authed sites the host has no value to pass. - A stale value is not harmless.
getComputedAcceptAttributefeedsallowedMimeTypesinto the file input'sacceptattribute, which filters what the OS picker will let the user select. A stale allowlist there makes a valid file unpickable, with no error and no override — worse than a server rejection, which at least explains itself.
If a fallback is ever wired up, the safe shape is: merge per key (fetched > host > defaults), and require hosts to omit unknown keys rather than send null/0, since those are exactly the values that silently disable validation.
Environment info
GutenbergKit trunk (801131cc). Affects both the iOS and Android libraries. Not browser-specific — it reproduces wherever the host app disables theme styles.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the early returns in ios/Sources/GutenbergKit/Sources/RESTAPIRepository.swift:93 and android/Gutenberg/src/main/java/org/wordpress/gutenberg/RESTAPIRepository.kt:90, then trace GBKitGlobal.swift:132, GBKitGlobal.kt:135, and src/utils/editor.jsx:27. Verify that editor settings are fetched when theme styles are disabled while themeStyles CSS remains gated by the setting. Reproduce the upload validation steps and confirm allowedMimeTypes and maxUploadFileSize reach the web layer on both platforms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, kotlin, swift
- Domain
- api, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100