From efd0df0468d46149ba68b66660b93f31b6318515 Mon Sep 17 00:00:00 2001 From: Manuel Leduc Date: Thu, 9 Jun 2022 16:39:47 +0200 Subject: [PATCH] XWIKI-19800: Attachment Selector escaping improvements --- .../xwiki-platform-attachment-ui/pom.xml | 13 + .../resources/XWiki/AttachmentSelector.xml | 37 +- .../AttachmentSelectorPageTest.java | 330 ++++++++++++++++++ .../xwiki/attachment/TestNoScriptMacro.java | 72 ++++ 4 files changed, 441 insertions(+), 11 deletions(-) create mode 100644 xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/AttachmentSelectorPageTest.java create mode 100644 xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/TestNoScriptMacro.java diff --git a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/pom.xml b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/pom.xml index 9fb16396afd4..25a370f91394 100644 --- a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/pom.xml +++ b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/pom.xml @@ -43,5 +43,18 @@ ${project.version} runtime + + + org.xwiki.platform + xwiki-platform-test-page + ${project.version} + test + + + org.xwiki.platform + xwiki-platform-web-templates + ${project.version} + test + diff --git a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/main/resources/XWiki/AttachmentSelector.xml b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/main/resources/XWiki/AttachmentSelector.xml index fe50f4eb55cb..9173b9b1fa7d 100644 --- a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/main/resources/XWiki/AttachmentSelector.xml +++ b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/main/resources/XWiki/AttachmentSelector.xml @@ -117,7 +117,10 @@ $xwiki.jsx.use($attachmentPickerDocName) #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString))) #set ($deleteURL = $targetAttachDocument.getAttachmentURL($attachment.filename, 'delattachment', "xredirect=${returnURL}&form_token=$!{services.csrf.getToken()}") ) #set ($viewURL = $targetAttachDocument.getAttachmentURL($attachment.filename) )##{'name' : 'download', 'url' : $viewURL, 'rel' : '__blank'} - #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=${attachment.filename}&form_token=$!{services.csrf.getToken()}")) + #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, $escapetool.url({ + "${options.get('classname')}_${options.get('object')}_${options.get('property')}": ${attachment.filename}, + 'form_token': $!{services.csrf.getToken()} + }))) #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}, {'name' : 'delete', 'url' : $deleteURL}]) #end @@ -130,7 +133,9 @@ $xwiki.jsx.use($attachmentPickerDocName) *# #macro (attachmentPicker_displayStartFrame $boxOptions $currentValue) (% class="gallery_attachmentbox $!{boxOptions.cssClass} #if ("$!{boxOptions.value}" == $currentValue) current#{end}" %)((( - (% class="gallery_attachmenttitle" title="$!{boxOptions.value}" %)((($boxOptions.text))) + (% class="gallery_attachmenttitle" title="$services.rendering.escape($!{boxOptions.value}, 'xwiki/2.1')" %)((( + $services.rendering.escape($boxOptions.text, 'xwiki/2.1') + ))) (% class="gallery_attachmentframe" %)((( #end @@ -146,13 +151,13 @@ $xwiki.jsx.use($attachmentPickerDocName) ## Compute the attachment reference because there's no getter. #set ($attachmentReference = $services.model.createAttachmentReference($attachment.document.documentReference, $attachment.filename)) - #set ($attachmentStringReference = $services.model.serialize($attachmentReference, 'default')) + #set ($attachmentStringReference = $services.rendering.escape($services.model.serialize($attachmentReference, 'default'), 'xwiki/2.1')) #if ($attachment.isImage() && $options.displayImage) ## We add the version to the query string in order to invalidate the cache when an image attachment is replaced. #set ($queryString = $escapetool.url({'version': $attachment.version})) [[[[image:${attachmentStringReference}||width=180 queryString="$queryString"]]>>attach:$attachmentStringReference]] #else - * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$attachment.getFilename()(% %) + * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$services.rendering.escape($attachment.getFilename(), 'xwiki/2.1')(% %) * v$attachment.getVersion() (#dynamicsize($attachment.longSize)) * $services.localization.render('core.viewers.attachments.author', [$!{xwiki.getUserName($attachment.author, false)}]) $services.localization.render('core.viewers.attachments.date', [$!{xwiki.formatDate($attachment.date, 'dd/MM/yyyy hh:mm')}]) * (% class="buttonwrapper" %)[[${services.localization.render("${translationPrefix}.actions.download")}>>attach:${attachmentStringReference}||title="$services.localization.render("${translationPrefix}.actions.download")" rel="__blank" class="button"]](%%) @@ -1426,9 +1431,18 @@ $xwiki.ssx.use($xcontext.macro.doc.fullName)## #set ($displayImage = false) #end #if ($displayImage) - #set ($alt = "$!{xcontext.macro.params.alternateText}") - #set ($width = "$!{xcontext.macro.params.width}") - #set ($height = "$!{xcontext.macro.params.height}") + #set ($alt = '') + #set ($width = '') + #set ($height = '') + #if ($xcontext.macro.params.alternateText) + #set ($alt = "$services.rendering.escape($!{xcontext.macro.params.alternateText}, 'xwiki/2.1')") + #end + #if ($xcontext.macro.params.width) + #set ($width = "$services.rendering.escape($!{xcontext.macro.params.width}, 'xwiki/2.1')") + #end + #if ($xcontext.macro.params.height) + #set ($height = "$services.rendering.escape($!{xcontext.macro.params.height}, 'xwiki/2.1')") + #end #set ($imageParams = '') #if ("${width}" != '') #set($imageParams = "$!{imageParams} width=${width}") @@ -1493,9 +1507,9 @@ $xwiki.ssx.use($xcontext.macro.doc.fullName)## #set ($attachmentResource = '') #end #if ($displayImage) - (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:${attachmentResource}$!{imageParams}]]#if($withLink)>>attach:${attachmentResource}||rel=lightbox]]#{end}#end)))## + (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:$services.rendering.escape(${attachmentResource}, 'xwiki/2.1')$!{imageParams}]]#if($withLink)>>attach:$services.rendering.escape(${attachmentResource},'xwiki/2.1')||rel=lightbox]]#{end}#end)))## #else - (% class="$!{cssClass}" %)#if ("$!{attachmentResource}" != '' || $forceElement)#if ($withLink)[[attach:${attachmentResource}||rel=__blank]]#{else}(% class="displayed" %)#if($targetPermView)$!{attachmentName}#{else}Access Denied#{end}(% %)#{end}#end(%%)## + (% class="$!{cssClass}" %)#if ("$!{attachmentResource}" != '' || $forceElement)#if ($withLink)[[attach:${attachmentResource}||rel=__blank]]#{else}(% class="displayed" %)#if($targetPermView)$services.rendering.escape($!{attachmentName}, 'xwiki/2.1')#{else}Access Denied#{end}(% %)#{end}#end(%%)## #end #end @@ -1518,8 +1532,9 @@ $xwiki.ssx.use($xcontext.macro.doc.fullName)## #if ($hasTargetDoc) #set ($queryString.targetdocname = $targetdoc.fullName) #end - (% class="buttonwrapper" %)[[$buttontext>>${xcontext.macro.doc.fullName}||queryString="$escapetool.url($queryString)" - class="attachment-picker-start button" title="$buttontext"]](%%)## + #set ($linkLabel = $services.rendering.escape($services.rendering.escape($buttontext, 'xwiki/2.1'), 'xwiki/2.1')) + (% class="buttonwrapper" %)[[$linkLabel>>${xcontext.macro.doc.fullName}||queryString="$escapetool.url($queryString)" + class="attachment-picker-start button" title="$services.rendering.escape($buttontext, 'xwiki/2.1')"]](%%)## #end #end {{/velocity}} diff --git a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/AttachmentSelectorPageTest.java b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/AttachmentSelectorPageTest.java new file mode 100644 index 000000000000..b31399ee7652 --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/AttachmentSelectorPageTest.java @@ -0,0 +1,330 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.xwiki.attachment; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.stream.Stream; + +import org.apache.commons.io.IOUtils; +import org.apache.velocity.tools.generic.MathTool; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.xwiki.bridge.event.DocumentCreatedEvent; +import org.xwiki.component.manager.ComponentManager; +import org.xwiki.component.wiki.internal.bridge.DefaultContentParser; +import org.xwiki.model.reference.DocumentReference; +import org.xwiki.model.script.ModelScriptService; +import org.xwiki.observation.EventListener; +import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; +import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; +import org.xwiki.rendering.internal.macro.wikibridge.DefaultWikiMacroManager; +import org.xwiki.rendering.internal.macro.wikibridge.WikiMacroEventListener; +import org.xwiki.rendering.internal.syntax.SyntaxConverter; +import org.xwiki.rendering.script.RenderingScriptService; +import org.xwiki.rendering.syntax.Syntax; +import org.xwiki.rendering.wikimacro.internal.DefaultWikiMacroFactory; +import org.xwiki.rendering.wikimacro.internal.DefaultWikiMacroRenderer; +import org.xwiki.security.authorization.AuthorizationManager; +import org.xwiki.security.authorization.Right; +import org.xwiki.test.annotation.ComponentList; +import org.xwiki.test.page.HTML50ComponentList; +import org.xwiki.test.page.PageTest; +import org.xwiki.test.page.XWikiSyntax21ComponentList; +import org.xwiki.velocity.tools.CollectionTool; +import org.xwiki.xml.internal.html.filter.ControlCharactersFilter; + +import com.xpn.xwiki.XWikiException; +import com.xpn.xwiki.doc.XWikiDocument; +import com.xpn.xwiki.objects.BaseObject; +import com.xpn.xwiki.objects.classes.BaseClass; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.params.provider.Arguments.arguments; +import static org.mockito.Mockito.when; + +/** + * Test of {@code XWiki.AttachmentSelector}. + * + * @version $Id$ + * @since 14.5RC1 + * @since 14.4.2 + * @since 13.10.7 + */ +@HTML50ComponentList +@XWikiSyntax21ComponentList +@ComponentList({ + // Start RenderingScriptService + RenderingScriptService.class, + DefaultExtendedRenderingConfiguration.class, + RenderingConfigClassDocumentConfigurationSource.class, + SyntaxConverter.class, + // End RenderingScriptService + ControlCharactersFilter.class, + ModelScriptService.class, + TestNoScriptMacro.class, + // Start WikiMacroEventListener + WikiMacroEventListener.class, + DefaultWikiMacroFactory.class, + DefaultWikiMacroManager.class, + DefaultContentParser.class, + org.xwiki.rendering.internal.parser.DefaultContentParser.class, + DefaultWikiMacroRenderer.class + // End WikiMacroEventListener +}) +class AttachmentSelectorPageTest extends PageTest +{ + @BeforeEach + void setUp() throws Exception + { + registerVelocityTool("collectiontool", new CollectionTool()); + registerVelocityTool("mathtool", new MathTool()); + } + + @ParameterizedTest + @ValueSource(strings = { + "{{noscript}}println(\"Hello from noscript!\"){{/noscript}}.png", + "]] {{noscript}}println(\"Hello from noscript!\"){{/noscript}}.png" + }) + void renderDisplayImageFalse(String fileName) throws Exception + { + commonFixup(fileName); + + this.request.put("docname", "xwiki:Space.Test"); + this.request.put("classname", "xwiki:Space.Test"); + this.request.put("property", "avatar"); + this.request.put("object", "0"); + this.request.put("filter", "png"); + this.request.put("displayImage", "false"); + this.request.put("xpage", "plain"); + + Document document = renderHTMLPage(new DocumentReference("xwiki", "XWiki", "AttachmentSelector")); + + assertNotNull(document); + Element galleryAttachmentTitle = document.select(".gallery_attachmenttitle").get(1); + assertEquals(fileName, galleryAttachmentTitle.attr("title")); + assertEquals(fileName, galleryAttachmentTitle.text()); + assertEquals(fileName, document.select(".gallery_attachmentframe .filename").text()); + assertEquals(String.format("attach:xwiki:Space.Test@%s", fileName), + document.select(".gallery_attachmentframe a").attr("href")); + } + + @ParameterizedTest + @ValueSource(strings = { + "{{noscript}}println(\"Hello from noscript!\"){{/noscript}}.png", + "]] {{noscript}}println(\"Hello from noscript!\"){{/noscript}}.png" + }) + void renderDisplayImageTrue(String fileName) throws Exception + { + commonFixup(fileName); + + this.request.put("docname", "xwiki:Space.Test"); + this.request.put("classname", "xwiki:Space.Test"); + this.request.put("property", "avatar"); + this.request.put("object", "0"); + this.request.put("filter", "png"); + this.request.put("displayImage", "true"); + this.request.put("xpage", "plain"); + + Document document = renderHTMLPage(new DocumentReference("xwiki", "XWiki", "AttachmentSelector")); + assertNotNull(document); + Element galleryAttachmentTitle = document.select(".gallery_attachmenttitle").get(1); + assertEquals(fileName, galleryAttachmentTitle.attr("title")); + assertEquals(fileName, galleryAttachmentTitle.text()); + assertEquals(String.format("attach:xwiki:Space.Test@%s", fileName), + document.select(".gallery_attachmentframe a").attr("href")); + + Elements img = document.select(".gallery_attachmentframe img"); + assertEquals(String.format("xwiki:Space.Test@%s", fileName), img.attr("src")); + assertEquals(String.format("xwiki:Space.Test@%s", fileName), img.attr("alt")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroWidth(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "width=\"%s\" " + + "displayImage=\"true\"/}}", widthValue)); + + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("width")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroHeight(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "height=\"%s\" " + + "displayImage=\"true\"/}}", widthValue)); + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("height")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroAlternateText(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "alternateText=\"%s\" " + + "displayImage=\"true\"/}}", widthValue)); + xwikiDocument.setSyntax(Syntax.XWIKI_2_1); + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("alt")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroWidthWithLink(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "width=\"%s\" " + + "link=\"true\" " + + "displayImage=\"true\"/}}", widthValue)); + + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("width")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroHeightWithLink(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "height=\"%s\" " + + "link=\"true\" " + + "displayImage=\"true\"/}}", widthValue)); + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("height")); + } + + @ParameterizedTest + @MethodSource("attachmentSelectorMacroSource") + void attachmentSelectorMacroAlternateTextWithLink(String widthValue, String expectedWidth) throws Exception + { + attachmentSelectorMacroFixup(); + + XWikiDocument xwikiDocument = commonFixup("test.png"); + + xwikiDocument.setContent(String.format("{{attachmentSelector " + + "classname=\"Space.Test\" " + + "property=\"avatar\" " + + "savemode=\"direct\" " + + "alternateText=\"%s\" " + + "link=\"true\" " + + "displayImage=\"true\"/}}", widthValue)); + xwikiDocument.setSyntax(Syntax.XWIKI_2_1); + Document document = renderHTMLPage(xwikiDocument); + assertEquals(expectedWidth, document.select(".displayed img").attr("alt")); + } + + private void attachmentSelectorMacroFixup() throws Exception + { + DocumentReference attachmentSelectorDocumentReference = + new DocumentReference("xwiki", "XWiki", "AttachmentSelector"); + XWikiDocument xWikiDocument = loadPage(attachmentSelectorDocumentReference); + + // TODO: The code below is more generic than this test and should be moved to be reusable. + // Make the wiki component manager point to the default component manager. + this.componentManager.registerComponent(ComponentManager.class, "wiki", + this.componentManager.getInstance(ComponentManager.class)); + when(this.componentManager.getInstance(AuthorizationManager.class) + .hasAccess(Right.ADMIN, new DocumentReference("xwiki", "XWiki", "Admin"), + xWikiDocument.getDocumentReference().getWikiReference())).thenReturn(true); + // Simulate the event not thrown by page test for now. + this.componentManager.getInstance(EventListener.class, "wikimacrolistener") + .onEvent(new DocumentCreatedEvent(), xWikiDocument, null); + } + + private XWikiDocument commonFixup(String fileName) throws XWikiException, IOException + { + // Initialize a document containing an XClass definition and an XObject of this XClass. + // The interesting property is the avatar string field, which references the name of an attachment contained in + // the document itself too. + DocumentReference documentReference = new DocumentReference("xwiki", "Space", "Test"); + XWikiDocument xwikiDocument = this.xwiki.getDocument(documentReference, this.context); + BaseClass xClass = xwikiDocument.getXClass(); + xClass.addTextField("avatar", "Avatar", 10); + BaseObject baseObject = xwikiDocument.newXObject(xwikiDocument.getDocumentReference(), this.context); + baseObject.setStringValue("avatar", fileName); + // Simulates the file rename action. + xwikiDocument.setAttachment("tmp.png", IOUtils.toInputStream("", Charset.defaultCharset()), this.context); + xwikiDocument.getAttachment("tmp.png").setFilename(fileName); + xwikiDocument.setSyntax(Syntax.XWIKI_2_1); + + this.xwiki.saveDocument(xwikiDocument, this.context); + + this.context.setDoc(xwikiDocument); + + return xwikiDocument; + } + + public static Stream attachmentSelectorMacroSource() + { + return Stream.of( + arguments("{{noscript /~}~}", "{{noscript /}}"), + arguments("]] {{noscript /~}~}", "]] {{noscript /}}"), + arguments("]] {{noscript /~}~} [[", "]] {{noscript /}} [[") + ); + } +} diff --git a/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/TestNoScriptMacro.java b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/TestNoScriptMacro.java new file mode 100644 index 000000000000..a0cf70874af8 --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-ui/src/test/java/org/xwiki/attachment/TestNoScriptMacro.java @@ -0,0 +1,72 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.xwiki.attachment; + +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.slf4j.Logger; +import org.xwiki.component.annotation.Component; +import org.xwiki.rendering.block.Block; +import org.xwiki.rendering.macro.AbstractMacro; +import org.xwiki.rendering.transformation.MacroTransformationContext; + +import static java.util.Collections.emptyList; + +/** + * This script prints an error log when it is interpreted, making the test fail. + * + * @version $Id$ + * @since 14.5RC1 + * @since 14.4.2 + * @since 13.10.7 + */ +@Component +@Named("noscript") +@Singleton +public class TestNoScriptMacro extends AbstractMacro +{ + @Inject + private Logger logger; + + /** + * Default constructor. + */ + public TestNoScriptMacro() + { + super("NoScript", "No Script!"); + } + + @Override + public boolean supportsInlineMode() + { + return true; + } + + @Override + public List execute(Object parameters, String content, MacroTransformationContext context) + { + this.logger.error("SHOULD NOT BE CALLED"); + return emptyList(); + } +}