1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.macro.script

File NestedScriptMacroValidatorListener.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

12
19
3
1
116
69
10
0.53
6.33
3
3.33

Classes

Class Line # Actions
NestedScriptMacroValidatorListener 52 19 0% 10 3
0.911764791.2%
 

Contributing tests

This file is covered by 90 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.internal.macro.script;
21   
22    import javax.inject.Inject;
23    import javax.inject.Named;
24    import javax.inject.Singleton;
25   
26    import org.xwiki.component.annotation.Component;
27    import org.xwiki.observation.event.CancelableEvent;
28    import org.xwiki.rendering.block.Block;
29    import org.xwiki.rendering.block.MacroMarkerBlock;
30    import org.xwiki.rendering.block.MetaDataBlock;
31    import org.xwiki.rendering.block.match.ClassBlockMatcher;
32    import org.xwiki.rendering.block.match.MetadataBlockMatcher;
33    import org.xwiki.rendering.listener.MetaData;
34    import org.xwiki.rendering.macro.Macro;
35    import org.xwiki.rendering.macro.MacroId;
36    import org.xwiki.rendering.macro.MacroLookupException;
37    import org.xwiki.rendering.macro.MacroManager;
38    import org.xwiki.rendering.macro.script.ScriptMacro;
39    import org.xwiki.rendering.macro.script.ScriptMacroParameters;
40    import org.xwiki.rendering.transformation.MacroTransformationContext;
41   
42    /**
43    * Listens to {@link org.xwiki.script.event.ScriptEvaluatingEvent} and cancels the evaluation if the script
44    * is nested.
45    *
46    * @version $Id: 2e3f1fdf06b4b8ae57471fd22a39f7ed95ff749d $
47    * @since 2.5M1
48    */
49    @Component
50    @Named("nestedscriptmacrovalidator")
51    @Singleton
 
52    public class NestedScriptMacroValidatorListener extends AbstractScriptCheckerListener
53    {
54    /**
55    * Used to find the type of a Macro defined by a Macro Marker block; we're interested to prevent nested scripts only
56    * in Script macros.
57    */
58    @Inject
59    private MacroManager macroManager;
60   
 
61  552 toggle @Override
62    public String getName()
63    {
64  552 return "nestedscriptmacrovalidator";
65    }
66   
 
67  8737 toggle @Override
68    protected void check(CancelableEvent event, MacroTransformationContext context, ScriptMacroParameters parameters)
69    {
70    // Traverse the XDOM tree up to the root
71  8737 if (context.getCurrentMacroBlock() != null) {
72  8736 MacroMarkerBlock parent = context.getCurrentMacroBlock().getFirstBlock(
73    new ClassBlockMatcher(MacroMarkerBlock.class), Block.Axes.ANCESTOR);
74  8739 while (parent != null) {
75  1143 String parentId = parent.getId();
76  1143 try {
77  1143 Macro< ? > macro = this.macroManager.getMacro(new MacroId(parentId));
78  1143 if (macro instanceof ScriptMacro) {
79    // Find the
80  2 event.cancel(String.format("Nested scripts are not allowed. Current Script Macro [%s] "
81    + "(source [%s]) is executed inside Script Macro [%s] (source [%s])",
82    context.getCurrentMacroBlock().getId(),
83    extractSourceContentReference(context.getCurrentMacroBlock()), parentId,
84    extractSourceContentReference(parent)));
85  1141 } else if (macro instanceof NestedScriptMacroEnabled) {
86    // This macro has the right to produce script macro whatever the parent.
87  242 return;
88  899 } else if ("include".equals(parentId)) {
89    // Included documents intercept the chain of nested script macros with XWiki syntax
90    // TODO: find cleaner way. I don't think we can make include macro depends on script macro to
91    // use NestedScriptMacroEnabled, we should maybe find something more generic
92  898 return;
93    }
94    } catch (MacroLookupException exception) {
95    // Shouldn't happen, the parent macro was already successfully executed earlier
96    }
97  3 parent = parent.getFirstBlock(new ClassBlockMatcher(MacroMarkerBlock.class), Block.Axes.ANCESTOR);
98    }
99    }
100    }
101   
102    /**
103    * @param source the blocks from where to try to extract the source content
104    * @return the source content reference or null if none is found
105    */
 
106  4 toggle private String extractSourceContentReference(Block source)
107    {
108  4 String contentSource = null;
109  4 MetaDataBlock metaDataBlock =
110    source.getFirstBlock(new MetadataBlockMatcher(MetaData.SOURCE), Block.Axes.ANCESTOR);
111  4 if (metaDataBlock != null) {
112  0 contentSource = (String) metaDataBlock.getMetaData().getMetaData(MetaData.SOURCE);
113    }
114  4 return contentSource;
115    }
116    }