Skip to content
Permalink
Browse files Browse the repository at this point in the history
XWIKI-20327: Escape closing HTML macro in XWikiDocument#display
  • Loading branch information
michitux committed Dec 19, 2022
1 parent 7884d76 commit 0d54718
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
Expand Up @@ -220,6 +220,8 @@ public class XWikiDocument implements DocumentModelBridge, Cloneable

private static final String TM_FAILEDDOCUMENTPARSE = "core.document.error.failedParse";

private static final String CLOSE_HTML_MACRO = "{{/html}}";

/**
* An attachment waiting to be deleted at next document save.
*
Expand Down Expand Up @@ -3885,10 +3887,19 @@ public String display(String fieldname, String type, String pref, BaseObject obj
// We test if we're inside the rendering engine since it's also possible that this display() method is
// called directly from a template and in this case we only want HTML as a result and not wiki syntax.
// TODO: find a more generic way to handle html macro because this works only for XWiki 1.0 and XWiki 2.0
// Add the {{html}}{{/html}} only when result really contains html since it's not needed for pure text
if (isInRenderingEngine && !is10Syntax(wrappingSyntaxId) && HTMLUtils.containsElementText(result)) {
// Add the {{html}}{{/html}} only when result really contains html or { which could be part of an XWiki
// macro syntax since it's not needed for pure text
if (isInRenderingEngine && !is10Syntax(wrappingSyntaxId)
&& (HTMLUtils.containsElementText(result) || result.indexOf("{") != -1))
{
result.insert(0, "{{html clean=\"false\" wiki=\"false\"}}");
result.append("{{/html}}");
// Escape closing HTML macro syntax.
int startIndex = 0;
// Start searching at the last match to avoid scanning the whole string again.
while ((startIndex = result.indexOf(CLOSE_HTML_MACRO, startIndex)) != -1) {
result.replace(startIndex, startIndex + 2, "{{");
}
result.append(CLOSE_HTML_MACRO);
}

return result.toString();
Expand Down
Expand Up @@ -59,6 +59,7 @@
import com.xpn.xwiki.api.DocumentSection;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xpn.xwiki.objects.classes.PropertyClass;
import com.xpn.xwiki.objects.classes.TextAreaClass;
import com.xpn.xwiki.store.XWikiStoreInterface;
import com.xpn.xwiki.store.XWikiVersioningStoreInterface;
Expand All @@ -76,10 +77,12 @@
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -647,6 +650,30 @@ public void displayTemplate20()
assertEquals("<p>area</p>", this.document.display("area", "view", this.oldcore.getXWikiContext()));
}

@Test
void displayEscapesClosingHTMLMacro()
{
this.oldcore.getXWikiContext().put("isInRenderingEngine", true);
when(this.xWiki.getCurrentContentSyntaxId(any())).thenReturn("xwiki/2.1");
this.document.setSyntax(Syntax.XWIKI_2_0);

BaseObject object = mock(BaseObject.class);
when(object.getOwnerDocument()).thenReturn(this.document);

BaseClass xClass = mock(BaseClass.class);
when(object.getXClass(any())).thenReturn(xClass);
PropertyClass propertyInterface = mock(PropertyClass.class);
when(xClass.get("mock")).thenReturn(propertyInterface);
doAnswer(call -> {
call.getArgument(0, StringBuffer.class).append("{{/html}}content{{/html}}");
return null;
}).when(propertyInterface).displayView(any(StringBuffer.class), eq("mock"), any(String.class), eq(object),
anyBoolean(), any(XWikiContext.class));

assertEquals("{{html clean=\"false\" wiki=\"false\"}}&#123;&#123;/html}}content&#123;&#123;/html}}{{/html}}",
this.document.display("mock", "view", object, this.oldcore.getXWikiContext()));
}

@Test
public void convertSyntax() throws XWikiException
{
Expand Down

0 comments on commit 0d54718

Please sign in to comment.