VYPR
Critical severityNVD Advisory· Published May 10, 2023· Updated Jan 27, 2025

Improper Neutralization of Script in Attributes in XWiki (X)HTML renderers

CVE-2023-32070

Description

XWiki Platform is a generic wiki platform. Prior to version 14.6-rc-1, HTML rendering didn't check for dangerous attributes/attribute values. This allowed cross-site scripting (XSS) attacks via attributes and link URLs, e.g., supported in XWiki syntax. This has been patched in XWiki 14.6-rc-1. There are no known workarounds apart from upgrading to a fixed version.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.rendering:xwiki-rendering-syntax-xhtmlMaven
< 14.6-rc-114.6-rc-1
org.xwiki.platform:xwiki-core-rendering-apiMaven
<= 3.0-milestone-2
org.xwiki.rendering:xwiki-rendering-syntax-htmlMaven
< 14.6-rc-114.6-rc-1
org.xwiki.rendering:xwiki-rendering-syntax-html5Maven
< 14.6-rc-114.6-rc-1
org.xwiki.rendering:xwiki-rendering-syntax-annotatedxhtmlMaven
< 14.6-rc-114.6-rc-1
org.xwiki.rendering:xwiki-rendering-syntax-annotatedhtml5Maven
< 14.6-rc-114.6-rc-1
org.xwiki.platform:xwiki-platform-annotation-coreMaven
< 14.6-rc-114.6-rc-1

Affected products

1

Patches

1
c40e2f5f9482

XRENDERING-663: Restrict allowed attributes in HTML rendering

https://github.com/xwiki/xwiki-renderingMichael HamannApr 29, 2022via ghsa
48 files changed · +330 117
  • xwiki-rendering-integration-tests/src/test/resources/simple/escape/escape15.test+3 3 modified
    @@ -20,16 +20,16 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikiexternallink"><a param="value" href="refe||rence">lab&gt;&gt;el~</a></span></p>
    +<p><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="refe||rence">lab&gt;&gt;el~</a></span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|url|-|refe||rence--><span class="wikiexternallink"><a param="value" href="refe||rence">lab&gt;&gt;el~</a></span><!--stopwikilink--></p>
    +<p><!--startwikilink:false|-|url|-|refe||rence--><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="refe||rence">lab&gt;&gt;el~</a></span><!--stopwikilink--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
     [[lab~>~>el~~~~>>refe~|~|rence||param="value"]]
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|url|-|refe||rence--><span class="wikiexternallink"><a param="value" href="refe||rence">lab&gt;&gt;el~</a></span><!--stopwikilink--></p>
    \ No newline at end of file
    +<p><!--startwikilink:false|-|url|-|refe||rence--><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="refe||rence">lab&gt;&gt;el~</a></span><!--stopwikilink--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/group/group9.test+2 2 modified
    @@ -29,7 +29,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<div param="value"><p>some text</p></div><div param="value"><p>some text</p></div>
    +<div data-xwiki-translated-attribute-param="value"><p>some text</p></div><div data-xwiki-translated-attribute-param="value"><p>some text</p></div>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -45,4 +45,4 @@ some text
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<div param="value"><p>some text</p></div><div param="value"><p>some text</p></div>
    \ No newline at end of file
    +<div data-xwiki-translated-attribute-param="value"><p>some text</p></div><div data-xwiki-translated-attribute-param="value"><p>some text</p></div>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/horizontalline/horizontalline5.test+2 2 modified
    @@ -12,7 +12,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<hr param="value"/>
    +<hr data-xwiki-translated-attribute-param="value"/>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -21,4 +21,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<html><hr param="value"/></html>
    \ No newline at end of file
    +<html><hr data-xwiki-translated-attribute-param="value"/></html>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/italic/italic8.test+1 1 modified
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><em><span a="b">something</span></em></p>
    +<p><em><span data-xwiki-translated-attribute-a="b">something</span></em></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/list/definitionlist7.test+2 2 modified
    @@ -21,7 +21,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<dl param="value"><dt>title</dt><dd>definition</dd></dl>
    +<dl data-xwiki-translated-attribute-param="value"><dt>title</dt><dd>definition</dd></dl>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -31,7 +31,7 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<dl param="value"><dt>title</dt><dd>definition</dd></dl>
    +<dl data-xwiki-translated-attribute-param="value"><dt>title</dt><dd>definition</dd></dl>
     .#-----------------------------------------------------
     .expect|plain/1.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/list/list13.test+2 2 modified
    @@ -42,7 +42,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<ul param="value"><li>item 1<ul param2="value2"><li>item 1.1<ul><li>item 1.1.1</li></ul></li></ul></li></ul>
    +<ul data-xwiki-translated-attribute-param="value"><li>item 1<ul data-xwiki-translated-attribute-param2="value2"><li>item 1.1<ul><li>item 1.1.1</li></ul></li></ul></li></ul>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -54,4 +54,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<ul param="value"><li>item 1<ul param2="value2"><li>item 1.1<ul><li>item 1.1.1</li></ul></li></ul></li></ul>
    \ No newline at end of file
    +<ul data-xwiki-translated-attribute-param="value"><li>item 1<ul data-xwiki-translated-attribute-param2="value2"><li>item 1.1<ul><li>item 1.1.1</li></ul></li></ul></li></ul>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/list/list8.test+2 2 modified
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<ul param1="value1" param2="value2"><li>item</li></ul>
    +<ul data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2"><li>item</li></ul>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -25,4 +25,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<html><ul param1="value1" param2="value2"><li>item</li></ul></html>
    \ No newline at end of file
    +<html><ul data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2"><li>item</li></ul></html>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/macros/macro10.test+3 3 modified
    @@ -44,12 +44,12 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<span param="value">formatmacro2</span><p><span a="b"><span param="value">formatmacro3</span> text</span></p><p><span a="b">text</span><span param="value">formatmacro4</span></p>
    +<span data-xwiki-translated-attribute-param="value">formatmacro2</span><p><span data-xwiki-translated-attribute-a="b"><span data-xwiki-translated-attribute-param="value">formatmacro3</span> text</span></p><p><span data-xwiki-translated-attribute-a="b">text</span><span data-xwiki-translated-attribute-param="value">formatmacro4</span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<!--startmacro:testformatmacro|-|--><span param="value">formatmacro2</span><!--stopmacro--><p><span a="b"><!--startmacro:testformatmacro|-|--><span param="value">formatmacro3</span><!--stopmacro--> text</span></p><p><span a="b">text</span><!--startmacro:testformatmacro|-|--><span param="value">formatmacro4</span><!--stopmacro--></p>
    +<!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro2</span><!--stopmacro--><p><span data-xwiki-translated-attribute-a="b"><!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro3</span><!--stopmacro--> text</span></p><p><span data-xwiki-translated-attribute-a="b">text</span><!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro4</span><!--stopmacro--></p>
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<!--startmacro:testformatmacro|-|--><span param="value">formatmacro2</span><!--stopmacro--><p><span a="b"><!--startmacro:testformatmacro|-|--><span param="value">formatmacro3</span><!--stopmacro--> text</span></p><p><span a="b">text</span><!--startmacro:testformatmacro|-|--><span param="value">formatmacro4</span><!--stopmacro--></p>
    \ No newline at end of file
    +<!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro2</span><!--stopmacro--><p><span data-xwiki-translated-attribute-a="b"><!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro3</span><!--stopmacro--> text</span></p><p><span data-xwiki-translated-attribute-a="b">text</span><!--startmacro:testformatmacro|-|--><span data-xwiki-translated-attribute-param="value">formatmacro4</span><!--stopmacro--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/paragraph/paragraph6.test+1 1 modified
    @@ -105,7 +105,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p param1="value1" param2="value2"><span param3="value3">hello</span> world</p><p><span param4="valueA">hello&nbsp;</span><span param4="valueB">world</span></p><p><strong><span param5="value4">hello</span></strong><span param5="value4">&nbsp;world</span></p><p><span param6="valueA">hello&nbsp;</span><span param7="valueB">world</span></p><p>before<span param="value">x</span><strong>y</strong>after</p><p>12<strong>34<span param="value">56</span>78</strong>90</p><p><span param="value">1<em>2</em></span><em>3</em></p><p><strong><span param1="value1">1</span></strong><strong><span param2="value2">2</span></strong></p>
    +<p data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2"><span data-xwiki-translated-attribute-param3="value3">hello</span> world</p><p><span data-xwiki-translated-attribute-param4="valueA">hello&nbsp;</span><span data-xwiki-translated-attribute-param4="valueB">world</span></p><p><strong><span data-xwiki-translated-attribute-param5="value4">hello</span></strong><span data-xwiki-translated-attribute-param5="value4">&nbsp;world</span></p><p><span data-xwiki-translated-attribute-param6="valueA">hello&nbsp;</span><span data-xwiki-translated-attribute-param7="valueB">world</span></p><p>before<span data-xwiki-translated-attribute-param="value">x</span><strong>y</strong>after</p><p>12<strong>34<span data-xwiki-translated-attribute-param="value">56</span>78</strong>90</p><p><span data-xwiki-translated-attribute-param="value">1<em>2</em></span><em>3</em></p><p><strong><span data-xwiki-translated-attribute-param1="value1">1</span></strong><strong><span data-xwiki-translated-attribute-param2="value2">2</span></strong></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/quote/quote3.test+2 2 modified
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<blockquote param1="value1" param2="value2"><p>line</p></blockquote>
    +<blockquote data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2"><p>line</p></blockquote>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -25,4 +25,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<blockquote param1="value1" param2="value2"><p>line</p></blockquote>
    \ No newline at end of file
    +<blockquote data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2"><p>line</p></blockquote>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/section/section6.test+2 2 modified
    @@ -17,7 +17,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<h1 id="Hheader" class="wikigeneratedid" param="value"><span>header</span></h1>
    +<h1 id="Hheader" class="wikigeneratedid" data-xwiki-translated-attribute-param="value"><span>header</span></h1>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -26,4 +26,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<html><h1 id="Hheader" class="wikigeneratedid" param="value"><span>header</span></h1></html>
    \ No newline at end of file
    +<html><h1 id="Hheader" class="wikigeneratedid" data-xwiki-translated-attribute-param="value"><span>header</span></h1></html>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/strikedout/strikedout4.test+1 1 modified
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><del><span a="b">something</span></del></p>
    +<p><del><span data-xwiki-translated-attribute-a="b">something</span></del></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/subscript/subscript2.test+2 2 modified
    @@ -2,7 +2,7 @@
     .input|xhtml/1.0
     .# Verify that SUB tag parameters are recognized.
     .#-----------------------------------------------------
    -<html><p><sub a="b">something</sub></p></html>
    +<html><p><sub data-xwiki-translated-attribute-a="b">something</sub></p></html>
     .#-----------------------------------------------------
     .expect|event/1.0
     .#-----------------------------------------------------
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><sub><span a="b">something</span></sub></p>
    +<p><sub><span data-xwiki-translated-attribute-a="b">something</span></sub></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/superscript/superscript2.test+2 2 modified
    @@ -2,7 +2,7 @@
     .input|xhtml/1.0
     .# Verify that SUP tag parameters are recognized.
     .#-----------------------------------------------------
    -<html><p><sup a="b">something</sup></p></html>
    +<html><p><sup data-xwiki-translated-attribute-a="b">something</sup></p></html>
     .#-----------------------------------------------------
     .expect|event/1.0
     .#-----------------------------------------------------
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><sup><span a="b">something</span></sup></p>
    +<p><sup><span data-xwiki-translated-attribute-a="b">something</span></sup></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/table/table3.test+2 2 modified
    @@ -43,7 +43,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<table a="b"><tr c="d"><th e="f" scope="col"><span g="h">cell1</span></th><td i="j"><span k="l">cell2</span></td></tr></table><table a="b"><tr c="d"><th e="f" scope="col"><span g="h">cell1</span></th><td i="j"><span k="l">cell2</span></td></tr></table>
    +<table data-xwiki-translated-attribute-a="b"><tr data-xwiki-translated-attribute-c="d"><th data-xwiki-translated-attribute-e="f" scope="col"><span data-xwiki-translated-attribute-g="h">cell1</span></th><td data-xwiki-translated-attribute-i="j"><span k="l">cell2</span></td></tr></table><table data-xwiki-translated-attribute-a="b"><tr data-xwiki-translated-attribute-c="d"><th data-xwiki-translated-attribute-e="f" scope="col"><span data-xwiki-translated-attribute-g="h">cell1</span></th><td data-xwiki-translated-attribute-i="j"><span k="l">cell2</span></td></tr></table>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -55,4 +55,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<table a="b"><tr c="d"><th e="f" scope="col"><span g="h">cell1</span></th><td i="j"><span k="l">cell2</span></td></tr></table><table a="b"><tr c="d"><th e="f" scope="col"><span g="h">cell1</span></th><td i="j"><span k="l">cell2</span></td></tr></table>
    \ No newline at end of file
    +<table data-xwiki-translated-attribute-a="b"><tr data-xwiki-translated-attribute-c="d"><th data-xwiki-translated-attribute-e="f" scope="col"><span data-xwiki-translated-attribute-g="h">cell1</span></th><td data-xwiki-translated-attribute-i="j"><span k="l">cell2</span></td></tr></table><table data-xwiki-translated-attribute-a="b"><tr data-xwiki-translated-attribute-c="d"><th data-xwiki-translated-attribute-e="f" scope="col"><span data-xwiki-translated-attribute-g="h">cell1</span></th><td data-xwiki-translated-attribute-i="j"><span k="l">cell2</span></td></tr></table>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/verbatim/verbatim6.test+2 2 modified
    @@ -12,7 +12,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<pre param="value">abc</pre>
    +<pre data-xwiki-translated-attribute-param="value">abc</pre>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -21,4 +21,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<html><pre param="value">abc</pre></html>
    +<html><pre data-xwiki-translated-attribute-param="value">abc</pre></html>
    
  • xwiki-rendering-integration-tests/src/test/resources/simple/verbatim/verbatim7.test+2 2 modified
    @@ -16,7 +16,7 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p param="value"><span param2="value2"><tt class="wikimodel-verbatim">abc</tt></span></p>
    +<p data-xwiki-translated-attribute-param="value"><span data-xwiki-translated-attribute-param2="value2"><tt class="wikimodel-verbatim">abc</tt></span></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -25,4 +25,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p param="value"><span param2="value2"><tt class="wikimodel-verbatim">abc</tt></span></p>
    \ No newline at end of file
    +<p data-xwiki-translated-attribute-param="value"><span data-xwiki-translated-attribute-param2="value2"><tt class="wikimodel-verbatim">abc</tt></span></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/image/image12.test+2 2 modified
    @@ -65,8 +65,8 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<img src="imageurl" param1="value1" param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><div class="figcaption"><p>Image <strong>Caption</strong></p></div><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><div class="figcaption"><p>Caption</p><ul><li>With</li><li>nested</li><li>list <span class="wikiexternallink"><a href="https://xwiki.org">and link</a></span> and [[fake link]].</li></ul></div>
    +<img src="imageurl" data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><div class="figcaption"><p>Image <strong>Caption</strong></p></div><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><div class="figcaption"><p>Caption</p><ul><li>With</li><li>nested</li><li>list <span class="wikiexternallink"><a href="https://xwiki.org">and link</a></span> and [[fake link]].</li></ul></div>
     .#-----------------------------------------------------
     .expect|html/5.0
     .#-----------------------------------------------------
    -<figure class="image"><img src="imageurl" param1="value1" param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><figcaption><p>Image <strong>Caption</strong></p></figcaption></figure><figure class="image"><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><figcaption><p>Caption</p><ul><li>With</li><li>nested</li><li>list <span class="wikiexternallink"><a href="https://xwiki.org">and link</a></span> and [[fake link]].</li></ul></figcaption></figure>
    \ No newline at end of file
    +<figure class="image"><img src="imageurl" data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><figcaption><p>Image <strong>Caption</strong></p></figcaption></figure><figure class="image"><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><figcaption><p>Caption</p><ul><li>With</li><li>nested</li><li>list <span class="wikiexternallink"><a href="https://xwiki.org">and link</a></span> and [[fake link]].</li></ul></figcaption></figure>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/image/image1.test+3 3 modified
    @@ -16,11 +16,11 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><img src="imageurl" param1="value1" param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><br/><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/></p>
    +<p><img src="imageurl" data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><br/><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|my.png--><img src="imageurl" param1="value1" param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><!--stopimage--><br/><!--startimage:false|-|attach|-|Space.ExistingPage@my.png--><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    +<p><!--startimage:false|-|attach|-|my.png--><img src="imageurl" data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><!--stopimage--><br/><!--startimage:false|-|attach|-|Space.ExistingPage@my.png--><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -29,4 +29,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|my.png--><img src="imageurl" param1="value1" param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><!--stopimage--><br/><!--startimage:false|-|attach|-|Space.ExistingPage@my.png--><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    \ No newline at end of file
    +<p><!--startimage:false|-|attach|-|my.png--><img src="imageurl" data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" id="Imy.png" class="wikigeneratedid" alt="my.png"/><!--stopimage--><br/><!--startimage:false|-|attach|-|Space.ExistingPage@my.png--><img src="imageurl" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/image/image8.test+3 3 modified
    @@ -15,16 +15,16 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><img src="imageurl" param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/></p>
    +<p><img src="imageurl" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png?param1=value1--><img src="imageurl" param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/><!--stopimage--></p>
    +<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png?param1=value1--><img src="imageurl" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/><!--stopimage--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
     [[image:Space.ExistingPage@my.png?param1=value1||param2="value2"]]
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png?param1=value1--><img src="imageurl" param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/><!--stopimage--></p>
    \ No newline at end of file
    +<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png?param1=value1--><img src="imageurl" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png3Fparam13Dvalue1" class="wikigeneratedid" alt="Space.ExistingPage@my.png?param1=value1"/><!--stopimage--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/image/image9.test+3 3 modified
    @@ -15,16 +15,16 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><img src="imageurl?param1=value1" param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/></p>
    +<p><img src="imageurl?param1=value1" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png|-|queryString="param1=value1"--><img src="imageurl?param1=value1" param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    +<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png|-|queryString="param1=value1"--><img src="imageurl?param1=value1" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.1
     .#-----------------------------------------------------
     [[image:Space.ExistingPage@my.png||queryString="param1=value1" param2="value2"]]
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png|-|queryString="param1=value1"--><img src="imageurl?param1=value1" param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    \ No newline at end of file
    +<p><!--startimage:false|-|attach|-|Space.ExistingPage@my.png|-|queryString="param1=value1"--><img src="imageurl?param1=value1" data-xwiki-translated-attribute-param2="value2" id="ISpace.ExistingPage40my.png" class="wikigeneratedid" alt="Space.ExistingPage@my.png"/><!--stopimage--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/link/links14.test+3 3 modified
    @@ -16,16 +16,16 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikiexternallink"><a param="value" href="http://xwiki.org"><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/></a></span></p>
    +<p><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="http://xwiki.org"><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/></a></span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|url|-|http://xwiki.org--><span class="wikiexternallink"><a param="value" href="http://xwiki.org"><!--startimage:false|-|attach|-|attach.png--><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/><!--stopimage--></a></span><!--stopwikilink--></p>
    +<p><!--startwikilink:false|-|url|-|http://xwiki.org--><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="http://xwiki.org"><!--startimage:false|-|attach|-|attach.png--><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/><!--stopimage--></a></span><!--stopwikilink--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
     [[~[~[image:attach.png~|~|height="100" width="100"~]~]>>http://xwiki.org||param="value"]]
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|url|-|http://xwiki.org--><span class="wikiexternallink"><a param="value" href="http://xwiki.org"><!--startimage:false|-|attach|-|attach.png--><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/><!--stopimage--></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    +<p><!--startwikilink:false|-|url|-|http://xwiki.org--><span class="wikiexternallink"><a data-xwiki-translated-attribute-param="value" href="http://xwiki.org"><!--startimage:false|-|attach|-|attach.png--><img src="imageurl" height="100" width="100" id="Iattach.png" class="wikigeneratedid" alt="attach.png"/><!--stopimage--></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/link/links15.test+3 3 modified
    @@ -18,11 +18,11 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikiattachmentlink"><a param1="value1" param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><br/><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span></p>
    +<p><span class="wikiattachmentlink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><br/><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:true|-|attach|-|my.png--><span class="wikiattachmentlink"><a param1="value1" param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><!--stopwikilink--><br/><!--startwikilink:true|-|attach|-|Space.ExistingPage@my.png--><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span><!--stopwikilink--></p>
    +<p><!--startwikilink:true|-|attach|-|my.png--><span class="wikiattachmentlink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><!--stopwikilink--><br/><!--startwikilink:true|-|attach|-|Space.ExistingPage@my.png--><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span><!--stopwikilink--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -31,4 +31,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:true|-|attach|-|my.png--><span class="wikiattachmentlink"><a param1="value1" param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><!--stopwikilink--><br/><!--startwikilink:true|-|attach|-|Space.ExistingPage@my.png--><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    +<p><!--startwikilink:true|-|attach|-|my.png--><span class="wikiattachmentlink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="attachmenturl"><span class="wikigeneratedlinkcontent">my.png</span></a></span><!--stopwikilink--><br/><!--startwikilink:true|-|attach|-|Space.ExistingPage@my.png--><span class="wikiattachmentlink"><a href="attachmenturl"><span class="wikigeneratedlinkcontent">Space.ExistingPage@my.png</span></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/link/links19.test+2 2 modified
    @@ -4,7 +4,7 @@
     .# that the XHTML Renderer uses. Note that for now the HREF value is considered containing
     .# XWiki link syntax.
     .#----------------------------------------------------------------------------------------------
    -<p><a href="http://reference" param1="value1">http://reference</a></p>
    +<p><a href="http://reference" data-xwiki-translated-attribute-param1="value1">http://reference</a></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -29,4 +29,4 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikiexternallink"><a param1="value1" href="http://reference">http://reference</a></span></p>
    \ No newline at end of file
    +<p><span class="wikiexternallink"><a data-xwiki-translated-attribute-param1="value1" href="http://reference">http://reference</a></span></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/link/links2.test+3 3 modified
    @@ -21,11 +21,11 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikilink"><a param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span></p>
    +<p><span class="wikilink"><a data-xwiki-translated-attribute-param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|doc|-|Space.ExistingPage|-|queryString="param1=value1" anchor="anchor"--><span class="wikilink"><a param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--></p>
    +<p><!--startwikilink:false|-|doc|-|Space.ExistingPage|-|queryString="param1=value1" anchor="anchor"--><span class="wikilink"><a data-xwiki-translated-attribute-param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -37,4 +37,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|doc|-|Space.ExistingPage|-|queryString="param1=value1" anchor="anchor"--><span class="wikilink"><a param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    +<p><!--startwikilink:false|-|doc|-|Space.ExistingPage|-|queryString="param1=value1" anchor="anchor"--><span class="wikilink"><a data-xwiki-translated-attribute-param2="value2" href="viewurl?param1=value1#anchor"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--></p>
    \ No newline at end of file
    
  • xwiki-rendering-integration-tests/src/test/resources/wiki/link/links8.test+3 3 modified
    @@ -19,11 +19,11 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><span class="wikilink"><a param1="value1" param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><br/><span class="wikicreatelink"><a param="value" href="editurl">label</a></span></p>
    +<p><span class="wikilink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><br/><span class="wikicreatelink"><a data-xwiki-translated-attribute-param="value" href="editurl">label</a></span></p>
     .#-----------------------------------------------------
     .expect|annotatedxhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|doc|-|Space.ExistingPage--><span class="wikilink"><a param1="value1" param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--><br/><!--startwikilink:false|-|doc|-|Space.UnknownPage--><span class="wikicreatelink"><a param="value" href="editurl">label</a></span><!--stopwikilink--></p>
    +<p><!--startwikilink:false|-|doc|-|Space.ExistingPage--><span class="wikilink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--><br/><!--startwikilink:false|-|doc|-|Space.UnknownPage--><span class="wikicreatelink"><a data-xwiki-translated-attribute-param="value" href="editurl">label</a></span><!--stopwikilink--></p>
     .#-----------------------------------------------------
     .expect|xwiki/2.0
     .#-----------------------------------------------------
    @@ -32,4 +32,4 @@ endDocument
     .#-----------------------------------------------------
     .input|xhtml/1.0
     .#-----------------------------------------------------
    -<p><!--startwikilink:false|-|doc|-|Space.ExistingPage--><span class="wikilink"><a param1="value1" param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--><br/><!--startwikilink:false|-|doc|-|Space.UnknownPage--><span class="wikicreatelink"><a param="value" href="editurl">label</a></span><!--stopwikilink--></p>
    \ No newline at end of file
    +<p><!--startwikilink:false|-|doc|-|Space.ExistingPage--><span class="wikilink"><a data-xwiki-translated-attribute-param1="value1" data-xwiki-translated-attribute-param2="value2" href="viewurl"><span class="wikigeneratedlinkcontent">Space.ExistingPage</span></a></span><!--stopwikilink--><br/><!--startwikilink:false|-|doc|-|Space.UnknownPage--><span class="wikicreatelink"><a data-xwiki-translated-attribute-param="value" href="editurl">label</a></span><!--stopwikilink--></p>
    \ No newline at end of file
    
  • xwiki-rendering-macros/xwiki-rendering-macro-html/src/main/java/org/xwiki/rendering/internal/macro/html/HTMLMacroXHTMLRenderer.java+6 1 modified
    @@ -29,6 +29,7 @@
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Renderer that generates XHTML from a XDOM resulting from the parsing of text containing HTML mixed with wiki syntax.
    @@ -57,9 +58,13 @@ public class HTMLMacroXHTMLRenderer extends AbstractHTMLMacroRenderer
         @Inject
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         protected AbstractChainingPrintRenderer getSyntaxRenderer()
         {
    -        return new XHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, getListenerChain());
    +        return new XHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            getListenerChain());
         }
     }
    
  • xwiki-rendering-macros/xwiki-rendering-macro-html/src/main/java/org/xwiki/rendering/internal/macro/html/renderers/annotatedhtml5/HTMLMacroAnnotatedHTML5Renderer.java+6 1 modified
    @@ -30,6 +30,7 @@
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Renderer that generates Annotated HTML5 from a XDOM resulting from the parsing of text containing HTML mixed with
    @@ -59,9 +60,13 @@ public class HTMLMacroAnnotatedHTML5Renderer extends AbstractHTMLMacroRenderer
         @Inject
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         protected AbstractChainingPrintRenderer getSyntaxRenderer()
         {
    -        return new AnnotatedHTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, getListenerChain());
    +        return new AnnotatedHTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            getListenerChain());
         }
     }
    
  • xwiki-rendering-macros/xwiki-rendering-macro-html/src/main/java/org/xwiki/rendering/internal/macro/html/renderers/annotatedxhtml/HTMLMacroAnnotatedXHTMLRenderer.java+6 1 modified
    @@ -30,6 +30,7 @@
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Renderer that generates Annotated XHTML from a XDOM resulting from the parsing of text containing HTML mixed with
    @@ -61,9 +62,13 @@ public class HTMLMacroAnnotatedXHTMLRenderer extends AbstractHTMLMacroRenderer
         @Named("annotated")
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         protected AbstractChainingPrintRenderer getSyntaxRenderer()
         {
    -        return new AnnotatedXHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, getListenerChain());
    +        return new AnnotatedXHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            getListenerChain());
         }
     }
    
  • xwiki-rendering-macros/xwiki-rendering-macro-html/src/main/java/org/xwiki/rendering/internal/macro/html/renderers/html5/HTMLMacroHTML5Renderer.java+6 1 modified
    @@ -30,6 +30,7 @@
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Renderer that generates HTML5 from a XDOM resulting from the parsing of text containing HTML mixed with
    @@ -59,9 +60,13 @@ public class HTMLMacroHTML5Renderer extends AbstractHTMLMacroRenderer
         @Inject
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         protected AbstractChainingPrintRenderer getSyntaxRenderer()
         {
    -        return new HTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, getListenerChain());
    +        return new HTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            getListenerChain());
         }
     }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-annotatedhtml5/src/main/java/org/xwiki/rendering/internal/renderer/html5/AnnotatedHTML5ChainingRenderer.java+4 2 modified
    @@ -28,6 +28,7 @@
     import org.xwiki.rendering.listener.MetaData;
     import org.xwiki.rendering.listener.chaining.BlockStateChainingListener;
     import org.xwiki.rendering.listener.chaining.ListenerChain;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Convert listener events to annotated HTML5. See {@link AnnotatedHTML5Renderer} for more details on what Annotated
    @@ -55,12 +56,13 @@ public class AnnotatedHTML5ChainingRenderer extends HTML5ChainingRenderer
          * @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable because
          *            image rendering depends on how the underlying system wants to handle it. For example for XWiki we
          *            check if the image exists as a document attachments, we get its URL, etc.
    +     * @param htmlElementSanitizer the HTML element sanitizer to use
          * @param listenerChain the chain of listener filters used to compute various states
          */
         public AnnotatedHTML5ChainingRenderer(XHTMLLinkRenderer linkRenderer,
    -            XHTMLImageRenderer imageRenderer, ListenerChain listenerChain)
    +            XHTMLImageRenderer imageRenderer, HTMLElementSanitizer htmlElementSanitizer, ListenerChain listenerChain)
         {
    -        super(linkRenderer, imageRenderer, listenerChain);
    +        super(linkRenderer, imageRenderer, htmlElementSanitizer, listenerChain);
     
             this.macroRenderer = new XHTMLMacroRenderer();
     
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-annotatedhtml5/src/main/java/org/xwiki/rendering/internal/renderer/html5/AnnotatedHTML5Renderer.java+6 1 modified
    @@ -34,6 +34,7 @@
     import org.xwiki.rendering.listener.chaining.ListenerChain;
     import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Generates Annotated HTML5 (ie HTML5 containing metadata information, for example macro definition or
    @@ -67,6 +68,9 @@ public class AnnotatedHTML5Renderer extends AbstractChainingPrintRenderer implem
         @Named("annotated")
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         public void initialize() throws InitializationException
         {
    @@ -79,6 +83,7 @@ public void initialize() throws InitializationException
             chain.addListener(new BlockStateChainingListener(chain));
             chain.addListener(new EmptyBlockChainingListener(chain));
             chain.addListener(new MetaDataStateChainingListener(chain));
    -        chain.addListener(new AnnotatedHTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, chain));
    +        chain.addListener(new AnnotatedHTML5ChainingRenderer(this.linkRenderer, this.imageRenderer,
    +            this.htmlElementSanitizer, chain));
         }
     }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-annotatedhtml5/src/test/resources/annotatedhtml50/simple/monospace/monospace2.out.txt+1 1 modified
    @@ -1 +1 @@
    -<p><span a="b" class="monospace">monospace</span></p>
    \ No newline at end of file
    +<p><span data-xwiki-translated-attribute-a="b" class="monospace">monospace</span></p>
    \ No newline at end of file
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-annotatedxhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/AnnotatedXHTMLChainingRenderer.java+4 2 modified
    @@ -25,6 +25,7 @@
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.listener.MetaData;
     import org.xwiki.rendering.listener.chaining.ListenerChain;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Convert listener events to annotated XHTML. See {@link AnnotatedXHTMLChainingRenderer} for more details on
    @@ -52,12 +53,13 @@ public class AnnotatedXHTMLChainingRenderer extends XHTMLChainingRenderer
          * @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable because
          *            image rendering depends on how the underlying system wants to handle it. For example for XWiki we
          *            check if the image exists as a document attachments, we get its URL, etc.
    +     * @param htmlElementSanitizer the sanitizer to use for sanitizing HTML elements and attributes
          * @param listenerChain the chain of listener filters used to compute various states
          */
         public AnnotatedXHTMLChainingRenderer(XHTMLLinkRenderer linkRenderer,
    -        XHTMLImageRenderer imageRenderer, ListenerChain listenerChain)
    +        XHTMLImageRenderer imageRenderer, HTMLElementSanitizer htmlElementSanitizer, ListenerChain listenerChain)
         {
    -        super(linkRenderer, imageRenderer, listenerChain);
    +        super(linkRenderer, imageRenderer, htmlElementSanitizer, listenerChain);
     
             this.macroRenderer = new XHTMLMacroRenderer();
     
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-annotatedxhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/AnnotatedXHTMLRenderer.java+6 1 modified
    @@ -34,6 +34,7 @@
     import org.xwiki.rendering.listener.chaining.ListenerChain;
     import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Generates Annotated XHTML (ie XHTML containing metadata information, for example macro definition or
    @@ -67,6 +68,9 @@ public class AnnotatedXHTMLRenderer extends AbstractChainingPrintRenderer implem
         @Named("annotated")
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         public void initialize() throws InitializationException
         {
    @@ -79,6 +83,7 @@ public void initialize() throws InitializationException
             chain.addListener(new BlockStateChainingListener(chain));
             chain.addListener(new EmptyBlockChainingListener(chain));
             chain.addListener(new MetaDataStateChainingListener(chain));
    -        chain.addListener(new AnnotatedXHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, chain));
    +        chain.addListener(new AnnotatedXHTMLChainingRenderer(this.linkRenderer, this.imageRenderer,
    +            this.htmlElementSanitizer, chain));
         }
     }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-html5/src/main/java/org/xwiki/rendering/internal/renderer/html5/HTML5ChainingRenderer.java+6 4 modified
    @@ -20,13 +20,15 @@
     package org.xwiki.rendering.internal.renderer.html5;
     
     import java.util.HashMap;
    +import java.util.LinkedHashMap;
     import java.util.Map;
     
     import org.xwiki.rendering.internal.renderer.xhtml.XHTMLChainingRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
     import org.xwiki.rendering.listener.Format;
     import org.xwiki.rendering.listener.chaining.ListenerChain;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Convert listener events to HTML5.
    @@ -53,22 +55,22 @@ public class HTML5ChainingRenderer extends XHTMLChainingRenderer
          * @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable because
          * image rendering depends on how the underlying system wants to handle it. For example for XWiki we check if the
          * image exists as a document attachments, we get its URL, etc.
    +     * @param htmlElementSanitizer the sanitizer to use for sanitizing HTML elements and attributes
          * @param listenerChain the chain of listener filters used to compute various states
          */
         public HTML5ChainingRenderer(XHTMLLinkRenderer linkRenderer,
    -            XHTMLImageRenderer imageRenderer,
    +            XHTMLImageRenderer imageRenderer, HTMLElementSanitizer htmlElementSanitizer,
                 ListenerChain listenerChain)
         {
    -        super(linkRenderer, imageRenderer, listenerChain);
    +        super(linkRenderer, imageRenderer, htmlElementSanitizer, listenerChain);
         }
     
         @Override
         public void beginFormat(Format format, Map<String, String> parameters)
         {
             // Right now, the only difference with the super class is about the "monospace" format
             if (format == Format.MONOSPACE) {
    -            Map<String, String> attributes = new HashMap<>();
    -            attributes.putAll(parameters);
    +            Map<String, String> attributes = new LinkedHashMap<>(parameters);
                 String cssClass = "monospace";
                 // The element may already have a class
                 if (attributes.containsKey(PROP_CLASS)) {
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-html5/src/main/java/org/xwiki/rendering/internal/renderer/html5/HTML5Renderer.java+6 1 modified
    @@ -34,6 +34,7 @@
     import org.xwiki.rendering.listener.chaining.ListenerChain;
     import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Generates HTML5 from a {@link org.xwiki.rendering.block.XDOM} object being traversed.
    @@ -62,6 +63,9 @@ public class HTML5Renderer extends AbstractChainingPrintRenderer implements Init
         @Inject
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         public void initialize() throws InitializationException
         {
    @@ -74,7 +78,8 @@ public void initialize() throws InitializationException
             chain.addListener(new BlockStateChainingListener(chain));
             chain.addListener(new EmptyBlockChainingListener(chain));
             chain.addListener(new MetaDataStateChainingListener(chain));
    -        chain.addListener(new HTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, chain));
    +        chain.addListener(new HTML5ChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            chain));
         }
     }
     
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-html5/src/test/java/org/xwiki/rendering/internal/html5/HTML5ChainingRendererTest.java+2 2 modified
    @@ -24,9 +24,9 @@
     
     import org.junit.Before;
     import org.junit.Test;
    +import org.xwiki.rendering.internal.renderer.html5.HTML5ChainingRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
     import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
    -import org.xwiki.rendering.internal.renderer.html5.HTML5ChainingRenderer;
     import org.xwiki.rendering.listener.Format;
     import org.xwiki.rendering.listener.chaining.ListenerChain;
     import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
    @@ -58,7 +58,7 @@ public void setUp() throws Exception
             linkRenderer = mock(XHTMLLinkRenderer.class);
             imageRenderer = mock(XHTMLImageRenderer.class);
             listenerChain = new ListenerChain();
    -        chainingRenderer = new HTML5ChainingRenderer(linkRenderer, imageRenderer, listenerChain);
    +        chainingRenderer = new HTML5ChainingRenderer(linkRenderer, imageRenderer, null, listenerChain);
             printer = new DefaultWikiPrinter();
             chainingRenderer.setPrinter(printer);
         }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml5/src/test/resources/xhtml5/simple/monospace/monospace2.inout.txt+1 1 modified
    @@ -1 +1 @@
    -<p><span a="b" class="monospace">monospace</span></p>
    \ No newline at end of file
    +<p><span data-xwiki-translated-attribute-a="b" class="monospace">monospace</span></p>
    \ No newline at end of file
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/parser/xhtml/wikimodel/XHTMLXWikiGeneratorListener.java+47 1 modified
    @@ -19,10 +19,12 @@
      */
     package org.xwiki.rendering.internal.parser.xhtml.wikimodel;
     
    +import java.util.LinkedHashMap;
     import java.util.Map;
     import java.util.regex.Matcher;
     import java.util.regex.Pattern;
     
    +import org.apache.commons.lang3.tuple.ImmutablePair;
     import org.apache.commons.lang3.tuple.Pair;
     import org.xwiki.rendering.internal.parser.wikimodel.DefaultXWikiGeneratorListener;
     import org.xwiki.rendering.listener.Listener;
    @@ -32,6 +34,7 @@
     import org.xwiki.rendering.parser.ResourceReferenceParser;
     import org.xwiki.rendering.parser.StreamParser;
     import org.xwiki.rendering.renderer.PrintRendererFactory;
    +import org.xwiki.rendering.renderer.printer.XHTMLWikiPrinter;
     import org.xwiki.rendering.syntax.Syntax;
     import org.xwiki.rendering.util.IdGenerator;
     import org.xwiki.rendering.wikimodel.WikiFormat;
    @@ -204,7 +207,7 @@ private static WikiParameters cleanParametersFromMetadata(WikiParameters paramet
             for (WikiParameter parameter : parameters) {
                 boolean acceptParameter = !(parameter.getKey().startsWith(METADATA_ATTRIBUTE_PREFIX)
                     || (
    -                    parameter.getKey().equals(CLASS_ATTRIBUTE) && parameter.getValue().equals(METADATA_CONTAINER_CLASS)
    +                parameter.getKey().equals(CLASS_ATTRIBUTE) && parameter.getValue().equals(METADATA_CONTAINER_CLASS)
                 ));
                 if (acceptParameter) {
                     wikiParameters = wikiParameters.addParameter(parameter.getKey(), parameter.getValue());
    @@ -288,4 +291,47 @@ public void endFormat(WikiFormat format)
                 super.endFormat(format);
             }
         }
    +
    +    @Override
    +    protected Map<String, String> convertParameters(WikiParameters params)
    +    {
    +        return maybeRemoveAttributePrefix(super.convertParameters(params));
    +    }
    +
    +    @Override
    +    protected Pair<Map<String, String>, Map<String, String>> convertAndSeparateParameters(WikiParameters params)
    +    {
    +        Pair<Map<String, String>, Map<String, String>> result = super.convertAndSeparateParameters(params);
    +        Map<String, String> genericParameters = result.getRight();
    +
    +        if (!genericParameters.isEmpty()) {
    +            genericParameters = maybeRemoveAttributePrefix(genericParameters);
    +        }
    +
    +        return new ImmutablePair<>(result.getLeft(), genericParameters);
    +    }
    +
    +    private Map<String, String> maybeRemoveAttributePrefix(Map<String, String> attributes)
    +    {
    +        Map<String, String> result;
    +
    +        if (!attributes.isEmpty()) {
    +            result = new LinkedHashMap<>();
    +
    +            for (Map.Entry<String, String> entry : attributes.entrySet()) {
    +                String newKey;
    +                if (entry.getKey().startsWith(XHTMLWikiPrinter.TRANSLATED_ATTRIBUTE_PREFIX)) {
    +                    newKey = entry.getKey().substring(XHTMLWikiPrinter.TRANSLATED_ATTRIBUTE_PREFIX.length());
    +                } else {
    +                    newKey = entry.getKey();
    +                }
    +
    +                result.put(newKey, entry.getValue());
    +            }
    +        } else {
    +            result = attributes;
    +        }
    +
    +        return result;
    +    }
     }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/XHTMLChainingRenderer.java+18 8 modified
    @@ -41,6 +41,7 @@
     import org.xwiki.rendering.syntax.Syntax;
     import org.xwiki.rendering.syntax.SyntaxType;
     import org.xwiki.xml.html.HTMLConstants;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Convert listener events to XHTML.
    @@ -65,24 +66,28 @@ public class XHTMLChainingRenderer extends AbstractChainingPrintRenderer
     
         private XHTMLImageRenderer imageRenderer;
     
    +    private final HTMLElementSanitizer htmlElementSanitizer;
    +
         private XHTMLWikiPrinter xhtmlWikiPrinter;
     
         /**
    -     * @param linkRenderer the object to render link events into XHTML. This is done so that it's pluggable because link
    -     *            rendering depends on how the underlying system wants to handle it. For example for XWiki we check if
    -     *            the document exists, we get the document URL, etc.
    -     * @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable because
    -     *            image rendering depends on how the underlying system wants to handle it. For example for XWiki we
    -     *            check if the image exists as a document attachments, we get its URL, etc.
    +     * @param linkRenderer the object to render link events into XHTML. This is done so that it's pluggable because
    +     *     link rendering depends on how the underlying system wants to handle it. For example for XWiki we check if the
    +     *     document exists, we get the document URL, etc.
    +     * @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable
    +     *     because image rendering depends on how the underlying system wants to handle it. For example for XWiki we
    +     *     check if the image exists as a document attachments, we get its URL, etc.
    +     * @param htmlElementSanitizer the sanitizer for XHTML elements
          * @param listenerChain the chain of listener filters used to compute various states
          */
         public XHTMLChainingRenderer(XHTMLLinkRenderer linkRenderer, XHTMLImageRenderer imageRenderer,
    -        ListenerChain listenerChain)
    +        HTMLElementSanitizer htmlElementSanitizer, ListenerChain listenerChain)
         {
             setListenerChain(listenerChain);
     
             this.linkRenderer = linkRenderer;
             this.imageRenderer = imageRenderer;
    +        this.htmlElementSanitizer = htmlElementSanitizer;
         }
     
         // State
    @@ -121,11 +126,16 @@ protected void popPrinter()
         protected XHTMLWikiPrinter getXHTMLWikiPrinter()
         {
             if (this.xhtmlWikiPrinter == null) {
    -            this.xhtmlWikiPrinter = new XHTMLWikiPrinter(getPrinter());
    +            this.xhtmlWikiPrinter = new XHTMLWikiPrinter(getPrinter(), getHtmlElementSanitizer());
             }
             return this.xhtmlWikiPrinter;
         }
     
    +    protected HTMLElementSanitizer getHtmlElementSanitizer()
    +    {
    +        return this.htmlElementSanitizer;
    +    }
    +
         // Events
     
         @Override
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/XHTMLRenderer.java+6 1 modified
    @@ -34,6 +34,7 @@
     import org.xwiki.rendering.listener.chaining.ListenerChain;
     import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
     import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Generates XHTML from a {@link org.xwiki.rendering.block.XDOM} object being traversed.
    @@ -62,6 +63,9 @@ public class XHTMLRenderer extends AbstractChainingPrintRenderer implements Init
         @Inject
         private XHTMLImageRenderer imageRenderer;
     
    +    @Inject
    +    private HTMLElementSanitizer htmlElementSanitizer;
    +
         @Override
         public void initialize() throws InitializationException
         {
    @@ -74,6 +78,7 @@ public void initialize() throws InitializationException
             chain.addListener(new BlockStateChainingListener(chain));
             chain.addListener(new EmptyBlockChainingListener(chain));
             chain.addListener(new MetaDataStateChainingListener(chain));
    -        chain.addListener(new XHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, chain));
    +        chain.addListener(new XHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, this.htmlElementSanitizer,
    +            chain));
         }
     }
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/test/java/org/xwiki/rendering/internal/renderer/xhtml/XHTMLChainingRendererTest.java+2 2 modified
    @@ -44,7 +44,7 @@ class XHTMLChainingRendererTest
         @Test
         void outputFigureCaptionEvents()
         {
    -        XHTMLChainingRenderer renderer = new XHTMLChainingRenderer(null, null, new ListenerChain());
    +        XHTMLChainingRenderer renderer = new XHTMLChainingRenderer(null, null, null, new ListenerChain());
             WikiPrinter wikiPrinter = new DefaultWikiPrinter();
             renderer.setPrinter(wikiPrinter);
             renderer.beginFigureCaption(Collections.emptyMap());
    @@ -57,7 +57,7 @@ void outputFigureCaptionEvents()
         @Test
         void onRawText()
         {
    -        XHTMLChainingRenderer renderer = new XHTMLChainingRenderer(null, null, new ListenerChain());
    +        XHTMLChainingRenderer renderer = new XHTMLChainingRenderer(null, null, null, new ListenerChain());
             WikiPrinter wikiPrinter = new DefaultWikiPrinter();
             renderer.setPrinter(wikiPrinter);
             renderer.onRawText("xhtml/1.0", Syntax.XHTML_1_0);
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/test/resources/xhtml10/simple/monospace/monospace2.inout.txt+1 1 modified
    @@ -1 +1 @@
    -<p><tt><span a="b">monospace</span></tt></p>
    \ No newline at end of file
    +<p><tt><span data-xwiki-translated-attribute-a="b">monospace</span></tt></p>
    \ No newline at end of file
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/test/resources/xhtml10/specific/bold/bold4.test+2 2 modified
    @@ -2,7 +2,7 @@
     .input|xhtml/1.0
     .# Verify that STRONG tag parameters are recognized.
     .#-----------------------------------------------------
    -<p><strong a="b" data-xwiki-parameter="value">something</strong></p>
    +<p><strong data-xwiki-translated-attribute-a="b" data-xwiki-parameter="value">something</strong></p>
     .#-----------------------------------------------------
     .expect|event/1.0
     .#-----------------------------------------------------
    @@ -16,4 +16,4 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p><strong><span a="b" data-xwiki-parameter="value">something</span></strong></p>
    \ No newline at end of file
    +<p><strong><span data-xwiki-translated-attribute-a="b" data-xwiki-parameter="value">something</span></strong></p>
    \ No newline at end of file
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/test/resources/xhtml10/specific/encoding/encoding1.test+2 2 modified
    @@ -3,7 +3,7 @@
     .# Verify that HTML entities can be parsed by the XHTML parser and are encoded properly
     .# Note that &nbsp; is transformed into a space.
     .#-------------------------------------------------------------------------------------
    -<p>&nbsp;&tilde;&euro;</p><p param1="val&#252;e">&#160;&#732;&#8364;</p>
    +<p>&nbsp;&tilde;&euro;</p><p data-xwiki-translated-attribute-param1="val&#252;e">&#160;&#732;&#8364;</p>
     .#-----------------------------------------------------
     .expect|event/1.0
     .#-----------------------------------------------------
    @@ -20,4 +20,4 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<p>&nbsp;˜€</p><p param1="valüe">&nbsp;˜€</p>
    \ No newline at end of file
    +<p>&nbsp;˜€</p><p data-xwiki-translated-attribute-param1="valüe">&nbsp;˜€</p>
    \ No newline at end of file
    
  • xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/test/resources/xhtml10/specific/group/group1.test+2 2 modified
    @@ -2,7 +2,7 @@
     .input|xhtml/1.0
     .# Verify that div tag parameters, also starting with data-xwiki-, are recognized.
     .#-----------------------------------------------------
    -<div a="b" data-xwiki-parameter="value">something</div>
    +<div data-xwiki-translated-attribute-a="b" data-xwiki-parameter="value">something</div>
     .#-----------------------------------------------------
     .expect|event/1.0
     .#-----------------------------------------------------
    @@ -16,4 +16,4 @@ endDocument
     .#-----------------------------------------------------
     .expect|xhtml/1.0
     .#-----------------------------------------------------
    -<div a="b" data-xwiki-parameter="value"><p>something</p></div>
    \ No newline at end of file
    +<div data-xwiki-translated-attribute-a="b" data-xwiki-parameter="value"><p>something</p></div>
    \ No newline at end of file
    
  • xwiki-rendering-xml/src/main/java/org/xwiki/rendering/renderer/printer/XHTMLWikiPrinter.java+132 21 modified
    @@ -19,10 +19,15 @@
      */
     package org.xwiki.rendering.renderer.printer;
     
    +import java.util.Arrays;
    +import java.util.LinkedHashMap;
     import java.util.Map;
     
     import org.apache.commons.lang3.StringUtils;
     import org.xml.sax.Attributes;
    +import org.xml.sax.helpers.AttributesImpl;
    +import org.xwiki.stability.Unstable;
    +import org.xwiki.xml.html.HTMLElementSanitizer;
     
     /**
      * Base toolkit class for all XHTML-based renderers. This printer handles whitespaces so that it prints "&nbsp;" when
    @@ -34,6 +39,21 @@
      */
     public class XHTMLWikiPrinter extends XMLWikiPrinter
     {
    +    /**
    +     * Prefix that is used for invalid/disallowed attributes.
    +     *
    +     * @since 14.6RC1
    +     */
    +    @Unstable
    +    public static final String TRANSLATED_ATTRIBUTE_PREFIX = "data-xwiki-translated-attribute-";
    +
    +    /**
    +     * The sanitizer used to restrict allowed elements and attributes, can be null (no restrictions).
    +     *
    +     * @since 14.6RC1
    +     */
    +    protected final HTMLElementSanitizer htmlElementSanitizer;
    +
         private int spaceCount;
     
         private boolean isInCData;
    @@ -50,15 +70,25 @@ public class XHTMLWikiPrinter extends XMLWikiPrinter
          * @param printer the object to which to write the XHTML output to
          */
         public XHTMLWikiPrinter(WikiPrinter printer)
    +    {
    +        this(printer, null);
    +    }
    +
    +    /**
    +     * @param printer the object to which to write the XHTML output to
    +     * @param htmlElementSanitizer the sanitizer to use for sanitizing elements and attributes
    +     */
    +    public XHTMLWikiPrinter(WikiPrinter printer, HTMLElementSanitizer htmlElementSanitizer)
         {
             super(printer);
    +        this.htmlElementSanitizer = htmlElementSanitizer;
         }
     
         /**
    -     * Use it to specify that the current element to print is standalone.
    -     * This value might be used to know if the first space should be printed with a simple space or a {@code &nbsp;}
    -     * entity. Note that the standalone value is automatically reset after first printing of a space, or when a text
    -     * is printed.
    +     * Use it to specify that the current element to print is standalone. This value might be used to know if the first
    +     * space should be printed with a simple space or a {@code &nbsp;} entity. Note that the standalone value is
    +     * automatically reset after first printing of a space, or when a text is printed.
    +     *
          * @since 12.2
          */
         public void setStandalone()
    @@ -78,58 +108,74 @@ public void printXML(String str)
         @Override
         public void printXMLElement(String name)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLElement(name);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLElement(name);
    +        }
         }
     
         @Override
         public void printXMLElement(String name, String[][] attributes)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLElement(name, attributes);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLElement(name, cleanAttributes(name, attributes));
    +        }
         }
     
         @Override
         public void printXMLElement(String name, Map<String, String> attributes)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLElement(name, attributes);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLElement(name, cleanAttributes(name, attributes));
    +        }
         }
     
         @Override
         public void printXMLStartElement(String name)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLStartElement(name);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLStartElement(name);
    +        }
         }
     
         @Override
         public void printXMLStartElement(String name, String[][] attributes)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLStartElement(name, attributes);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLStartElement(name, cleanAttributes(name, attributes));
    +        }
         }
     
         @Override
         public void printXMLStartElement(String name, Map<String, String> attributes)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLStartElement(name, attributes);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLStartElement(name, cleanAttributes(name, attributes));
    +        }
         }
     
         @Override
         public void printXMLStartElement(String name, Attributes attributes)
         {
    -        handleSpaceWhenStartElement();
    -        super.printXMLStartElement(name, attributes);
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenStartElement();
    +            super.printXMLStartElement(name, cleanAttributes(name, attributes));
    +        }
         }
     
         @Override
         public void printXMLEndElement(String name)
         {
    -        handleSpaceWhenEndlement();
    -        super.printXMLEndElement(name);
    -        this.elementEnded = true;
    +        if (this.htmlElementSanitizer == null || this.htmlElementSanitizer.isElementAllowed(name)) {
    +            handleSpaceWhenEndlement();
    +            super.printXMLEndElement(name);
    +            this.elementEnded = true;
    +        }
         }
     
         @Override
    @@ -185,6 +231,71 @@ private void handleSpaceWhenInText()
             }
         }
     
    +    private Map<String, String> cleanAttributes(String elementName, Map<String, String> attributes)
    +    {
    +        Map<String, String> cleanAttributes;
    +
    +        if (this.htmlElementSanitizer == null || attributes == null) {
    +            cleanAttributes = attributes;
    +        } else {
    +            cleanAttributes = new LinkedHashMap<>();
    +            for (Map.Entry<String, String> e : attributes.entrySet()) {
    +                if (this.htmlElementSanitizer.isAttributeAllowed(elementName, e.getKey(), e.getValue())) {
    +                    cleanAttributes.put(e.getKey(), e.getValue());
    +                } else {
    +                    cleanAttributes.put(TRANSLATED_ATTRIBUTE_PREFIX + e.getKey(), e.getValue());
    +                }
    +            }
    +        }
    +
    +        return cleanAttributes;
    +    }
    +
    +    private String[][] cleanAttributes(String elementName, String[][] attributes)
    +    {
    +        String[][] allowedAttributes;
    +        if (this.htmlElementSanitizer == null || attributes == null) {
    +            allowedAttributes = attributes;
    +        } else {
    +            allowedAttributes = Arrays.stream(attributes)
    +                .map(entry -> {
    +                    if (this.htmlElementSanitizer.isAttributeAllowed(elementName, entry[0], entry[1])) {
    +                        return entry;
    +                    } else {
    +                        return new String[] { TRANSLATED_ATTRIBUTE_PREFIX + entry[0], entry[1] };
    +                    }
    +                })
    +                .toArray(String[][]::new);
    +        }
    +
    +        return allowedAttributes;
    +    }
    +
    +    private Attributes cleanAttributes(String elementName, Attributes attributes)
    +    {
    +        Attributes allowedAttribute;
    +
    +        if (this.htmlElementSanitizer == null || attributes == null) {
    +            allowedAttribute = attributes;
    +        } else {
    +            allowedAttribute = new AttributesImpl();
    +
    +            for (int i = 0; i < attributes.getLength(); ++i) {
    +                if (this.htmlElementSanitizer.isAttributeAllowed(elementName, attributes.getQName(i),
    +                    attributes.getValue(i)))
    +                {
    +                    ((AttributesImpl) allowedAttribute).addAttribute(null, null, attributes.getQName(i),
    +                        null, attributes.getValue(i));
    +                } else {
    +                    ((AttributesImpl) allowedAttribute).addAttribute(null, null,
    +                        TRANSLATED_ATTRIBUTE_PREFIX + attributes.getQName(i), null, attributes.getValue(i));
    +                }
    +            }
    +        }
    +
    +        return allowedAttribute;
    +    }
    +
         private void handleSpaceWhenStartElement()
         {
             // Use case: <tag1>something <tag2>...
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.