This issue has been created
 
 
XWiki Platform / cid:jira-generated-image-avatar-9b74ccd3-ce85-435c-a344-d17e2fa38104 XWIKI-25417 Open

A concurrent call to getXDOM can replace the prepared content of a document with its unprepared content

 
View issue   ยท   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-8e188cce-0c39-4e5d-8799-832eadaeafcf Michael Hamann created this issue on 20/Oct/26 09:50
 
Summary: A concurrent call to getXDOM can replace the prepared content of a document with its unprepared content
Issue Type: cid:jira-generated-image-avatar-9b74ccd3-ce85-435c-a344-d17e2fa38104 Bug
Affects Versions: 17.10.0
Assignee: Unassigned
Components: Old Core
Created: 20/Oct/26 09:50
Labels: performance
Priority: cid:jira-generated-image-static-minor-75a4725d-fe8b-4de7-9618-8c152fcdf676 Minor
Reporter: Michael Hamann
Description:

XWikiDocument#getXDOM() stores the XDOM it parses in the cached content without checking whether another thread prepared the content in the meantime. When a thread calls getXDOM() on a document whose content isn't parsed yet while another thread finishes getPreparedXDOM(), the parsed but unprepared XDOM can overwrite the prepared one, while the preparation date stays set.

getPreparedXDOM() then returns the unprepared XDOM as prepared until the content of the document changes. Rendering still works since macros are executed on unprepared blocks too, but the document loses the benefit of the cached preparation (e.g. the syntax highlighting of the code macro is computed again for each rendering).

A possible fix is to keep the XDOM and its preparation date together in a single immutable value held in an AtomicReference, and to let getXDOM() store its result only with compareAndSet(null, ...). This also removes the need to read the preparation date before the XDOM.

Found while reviewing XWIKI-25414, which doesn't change this behavior.