There is 1 comment.
 
 
XWiki Platform / cid:jira-generated-image-avatar-a6e19daf-214c-4595-b3b5-d53995dc3fa1 XWIKI-13438 Open

ConversionFilter should setup the XWiki Context and extract the wikiid from the URL

 
View issue   ยท   Add comment
 

1 comment

 
cid:jira-generated-image-avatar-d6a2c6dd-2ac2-430d-9dd9-742c1f348afa Vincent Massol on 17/Sep/26 17:20
 

Re-checked this on master (September 2026): the issue is still valid, but the code has moved enough that the title's premise no longer holds.

What is still broken

ConversionFilter pushes a bare ExecutionContext, with no XWiki Context in it:

  • ConversionFilter#doFilter() does execution.pushContext(new ExecutionContext())
  • DefaultModelContext#getCurrentEntityReference() reads the wiki id from the xwikicontext property of the Execution Context, and returns null when there is none
  • AbstractEntityComponentManager#getComponentManagerInternal() then skips the wiki and user Component Managers, so the context Component Manager falls back to the root one

As a result, during a WYSIWYG save any component contributed by an extension installed on a subwiki is invisible: the target syntax PrintRendererFactory and the HTMLCleaner looked up in DefaultHTMLConverter#fromHTML(), and also the converter enumeration in DefaultRequestParameterConverter#convert(), which itself goes through the context Component Manager. That is exactly the XWIKI-13437 symptom, and CKEditor still saves through this path (the RequiresHTMLConversion parameter).

What has changed since 2016

The URL to wiki id resolution now exists: XWiki#getXWiki(boolean, XWikiContext) extracts the EntityResourceReference from the URL and calls setWikiId(). But it is called from XWikiAction#execute(XWikiContext), that is after the filter chain. Utils#prepareContext() still hardcodes wikiId = "xwiki".

So the missing piece is no longer "extract the wikiid from the URL", since that code exists. What remains is only the ordering: the conversion happens before the wiki is known.

Also worth noting, since the comments above rely on it: XWikiContextInitializationFilter is still declared in web.xml but no longer has any filter-mapping at all. Only its subclass XWikiRESTContextInitializationFilter is mapped, on the REST servlet.

Why this is not a small fix

Three possible shapes, none of them cheap:

  1. Map XWikiContextInitializationFilter before ConversionFilter, as proposed in the comments above. This looks like a web.xml one-liner, but that filter runs checkAuth() and the full XWiki.getXWiki() for every action request, which XWikiAction then redoes, so we would pay a double authentication and a double URL resolution on every request. Its finally block also calls cleanupComponents() after the whole chain, that is after XWikiAction has already cleaned up.
  2. Initialize the context inside ConversionFilter and pop it before chain.doFilter(), leaving XWikiAction untouched. This is around 40 lines and much better contained, but ConversionFilter does not short-circuit: it pushes the context and calls the converter on every action request, so a full context initialization plus authentication would be paid per request. Adding a short-circuit is awkward because DefaultRequestParameterConverter discovers the other converters through the context Component Manager (we need the context to know whether we need the context), and getConverterParameterName() is protected rather than part of the role.
  3. The refactoring originally wanted: initialize the context once in a high priority filter and have XWikiAction reuse it. XWikiAction#initializeXWikiContext() calls form.reset(request) before XWiki.getXWiki() sets the wiki id, so the ordering of oldcore's main request path has to be reworked first.

Since the blast radius of options 1 and 2 is every action request while the benefit is limited to subwiki scoped extensions contributing rendering components, this is not a good candidate for a bug fixing day. Proving any of these fixes also requires a Docker functional test with a subwiki and a syntax installed on that subwiki.