• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<HTML>
2<BODY BGCOLOR="white">
3<PRE>
4<FONT color="green">001</FONT>    // Copyright (c) 2011, Mike Samuel<a name="line.1"></a>
5<FONT color="green">002</FONT>    // All rights reserved.<a name="line.2"></a>
6<FONT color="green">003</FONT>    //<a name="line.3"></a>
7<FONT color="green">004</FONT>    // Redistribution and use in source and binary forms, with or without<a name="line.4"></a>
8<FONT color="green">005</FONT>    // modification, are permitted provided that the following conditions<a name="line.5"></a>
9<FONT color="green">006</FONT>    // are met:<a name="line.6"></a>
10<FONT color="green">007</FONT>    //<a name="line.7"></a>
11<FONT color="green">008</FONT>    // Redistributions of source code must retain the above copyright<a name="line.8"></a>
12<FONT color="green">009</FONT>    // notice, this list of conditions and the following disclaimer.<a name="line.9"></a>
13<FONT color="green">010</FONT>    // Redistributions in binary form must reproduce the above copyright<a name="line.10"></a>
14<FONT color="green">011</FONT>    // notice, this list of conditions and the following disclaimer in the<a name="line.11"></a>
15<FONT color="green">012</FONT>    // documentation and/or other materials provided with the distribution.<a name="line.12"></a>
16<FONT color="green">013</FONT>    // Neither the name of the OWASP nor the names of its contributors may<a name="line.13"></a>
17<FONT color="green">014</FONT>    // be used to endorse or promote products derived from this software<a name="line.14"></a>
18<FONT color="green">015</FONT>    // without specific prior written permission.<a name="line.15"></a>
19<FONT color="green">016</FONT>    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS<a name="line.16"></a>
20<FONT color="green">017</FONT>    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT<a name="line.17"></a>
21<FONT color="green">018</FONT>    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<a name="line.18"></a>
22<FONT color="green">019</FONT>    // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE<a name="line.19"></a>
23<FONT color="green">020</FONT>    // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,<a name="line.20"></a>
24<FONT color="green">021</FONT>    // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,<a name="line.21"></a>
25<FONT color="green">022</FONT>    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<a name="line.22"></a>
26<FONT color="green">023</FONT>    // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER<a name="line.23"></a>
27<FONT color="green">024</FONT>    // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT<a name="line.24"></a>
28<FONT color="green">025</FONT>    // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN<a name="line.25"></a>
29<FONT color="green">026</FONT>    // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<a name="line.26"></a>
30<FONT color="green">027</FONT>    // POSSIBILITY OF SUCH DAMAGE.<a name="line.27"></a>
31<FONT color="green">028</FONT>    <a name="line.28"></a>
32<FONT color="green">029</FONT>    package org.owasp.html;<a name="line.29"></a>
33<FONT color="green">030</FONT>    <a name="line.30"></a>
34<FONT color="green">031</FONT>    import java.util.List;<a name="line.31"></a>
35<FONT color="green">032</FONT>    <a name="line.32"></a>
36<FONT color="green">033</FONT>    import javax.annotation.Nullable;<a name="line.33"></a>
37<FONT color="green">034</FONT>    import javax.annotation.concurrent.Immutable;<a name="line.34"></a>
38<FONT color="green">035</FONT>    <a name="line.35"></a>
39<FONT color="green">036</FONT>    /**<a name="line.36"></a>
40<FONT color="green">037</FONT>     * A policy that can be applied to an element to decide whether or not to<a name="line.37"></a>
41<FONT color="green">038</FONT>     * allow it in the output, possibly after transforming attributes.<a name="line.38"></a>
42<FONT color="green">039</FONT>     * &lt;p&gt;<a name="line.39"></a>
43<FONT color="green">040</FONT>     * Element policies are applied &lt;strong&gt;after&lt;/strong&gt;<a name="line.40"></a>
44<FONT color="green">041</FONT>     * {@link AttributePolicy attribute policies} so<a name="line.41"></a>
45<FONT color="green">042</FONT>     * they can be used to add extra attributes.<a name="line.42"></a>
46<FONT color="green">043</FONT>     *<a name="line.43"></a>
47<FONT color="green">044</FONT>     * @author Mike Samuel &lt;mikesamuel@gmail.com&gt;<a name="line.44"></a>
48<FONT color="green">045</FONT>     * @see HtmlPolicyBuilder#allowElements(ElementPolicy, String...)<a name="line.45"></a>
49<FONT color="green">046</FONT>     */<a name="line.46"></a>
50<FONT color="green">047</FONT>    @TCB public interface ElementPolicy {<a name="line.47"></a>
51<FONT color="green">048</FONT>      /**<a name="line.48"></a>
52<FONT color="green">049</FONT>       * @param elementName the lower-case element name.<a name="line.49"></a>
53<FONT color="green">050</FONT>       * @param attrs a list of alternating attribute names and values.<a name="line.50"></a>
54<FONT color="green">051</FONT>       *    The list may be added to or removed from.  When removing, be<a name="line.51"></a>
55<FONT color="green">052</FONT>       *    careful to remove both the name and its associated value.<a name="line.52"></a>
56<FONT color="green">053</FONT>       *<a name="line.53"></a>
57<FONT color="green">054</FONT>       * @return {@code null} to disallow the element, or the adjusted element name.<a name="line.54"></a>
58<FONT color="green">055</FONT>       */<a name="line.55"></a>
59<FONT color="green">056</FONT>      public @Nullable String apply(String elementName, List&lt;String&gt; attrs);<a name="line.56"></a>
60<FONT color="green">057</FONT>    <a name="line.57"></a>
61<FONT color="green">058</FONT>    <a name="line.58"></a>
62<FONT color="green">059</FONT>      /** Utilities for working with element policies. */<a name="line.59"></a>
63<FONT color="green">060</FONT>      public static final class Util {<a name="line.60"></a>
64<FONT color="green">061</FONT>        private Util() { /* uninstantiable */ }<a name="line.61"></a>
65<FONT color="green">062</FONT>    <a name="line.62"></a>
66<FONT color="green">063</FONT>        /**<a name="line.63"></a>
67<FONT color="green">064</FONT>         * Given zero or more element policies, returns an element policy equivalent<a name="line.64"></a>
68<FONT color="green">065</FONT>         * to applying them in order failing early if any of them fails.<a name="line.65"></a>
69<FONT color="green">066</FONT>         */<a name="line.66"></a>
70<FONT color="green">067</FONT>        public static final ElementPolicy join(ElementPolicy... policies) {<a name="line.67"></a>
71<FONT color="green">068</FONT>    <a name="line.68"></a>
72<FONT color="green">069</FONT>          class PolicyJoiner {<a name="line.69"></a>
73<FONT color="green">070</FONT>            ElementPolicy last = null;<a name="line.70"></a>
74<FONT color="green">071</FONT>            ElementPolicy out = null;<a name="line.71"></a>
75<FONT color="green">072</FONT>    <a name="line.72"></a>
76<FONT color="green">073</FONT>            void join(ElementPolicy p) {<a name="line.73"></a>
77<FONT color="green">074</FONT>              if (p == REJECT_ALL_ELEMENT_POLICY) {<a name="line.74"></a>
78<FONT color="green">075</FONT>                out = p;<a name="line.75"></a>
79<FONT color="green">076</FONT>              } else if (out != REJECT_ALL_ELEMENT_POLICY) {<a name="line.76"></a>
80<FONT color="green">077</FONT>                if (p instanceof JoinedElementPolicy) {<a name="line.77"></a>
81<FONT color="green">078</FONT>                  JoinedElementPolicy jep = (JoinedElementPolicy) p;<a name="line.78"></a>
82<FONT color="green">079</FONT>                  join(jep.first);<a name="line.79"></a>
83<FONT color="green">080</FONT>                  join(jep.second);<a name="line.80"></a>
84<FONT color="green">081</FONT>                } else if (p != last) {<a name="line.81"></a>
85<FONT color="green">082</FONT>                  last = p;<a name="line.82"></a>
86<FONT color="green">083</FONT>                  if (out == null || out == IDENTITY_ELEMENT_POLICY) {<a name="line.83"></a>
87<FONT color="green">084</FONT>                    out = p;<a name="line.84"></a>
88<FONT color="green">085</FONT>                  } else if (p != IDENTITY_ELEMENT_POLICY) {<a name="line.85"></a>
89<FONT color="green">086</FONT>                    out = new JoinedElementPolicy(out, p);<a name="line.86"></a>
90<FONT color="green">087</FONT>                  }<a name="line.87"></a>
91<FONT color="green">088</FONT>                }<a name="line.88"></a>
92<FONT color="green">089</FONT>              }<a name="line.89"></a>
93<FONT color="green">090</FONT>            }<a name="line.90"></a>
94<FONT color="green">091</FONT>          }<a name="line.91"></a>
95<FONT color="green">092</FONT>    <a name="line.92"></a>
96<FONT color="green">093</FONT>          PolicyJoiner pu = new PolicyJoiner();<a name="line.93"></a>
97<FONT color="green">094</FONT>          for (ElementPolicy policy : policies) {<a name="line.94"></a>
98<FONT color="green">095</FONT>            if (policy == null) { continue; }<a name="line.95"></a>
99<FONT color="green">096</FONT>            pu.join(policy);<a name="line.96"></a>
100<FONT color="green">097</FONT>          }<a name="line.97"></a>
101<FONT color="green">098</FONT>          return pu.out != null ? pu.out : IDENTITY_ELEMENT_POLICY;<a name="line.98"></a>
102<FONT color="green">099</FONT>        }<a name="line.99"></a>
103<FONT color="green">100</FONT>    <a name="line.100"></a>
104<FONT color="green">101</FONT>      }<a name="line.101"></a>
105<FONT color="green">102</FONT>    <a name="line.102"></a>
106<FONT color="green">103</FONT>      public static final ElementPolicy IDENTITY_ELEMENT_POLICY<a name="line.103"></a>
107<FONT color="green">104</FONT>          = new ElementPolicy() {<a name="line.104"></a>
108<FONT color="green">105</FONT>        public String apply(String elementName, List&lt;String&gt; attrs) {<a name="line.105"></a>
109<FONT color="green">106</FONT>          return elementName;<a name="line.106"></a>
110<FONT color="green">107</FONT>        }<a name="line.107"></a>
111<FONT color="green">108</FONT>      };<a name="line.108"></a>
112<FONT color="green">109</FONT>    <a name="line.109"></a>
113<FONT color="green">110</FONT>      public static final ElementPolicy REJECT_ALL_ELEMENT_POLICY<a name="line.110"></a>
114<FONT color="green">111</FONT>          = new ElementPolicy() {<a name="line.111"></a>
115<FONT color="green">112</FONT>        public @Nullable String apply(String elementName, List&lt;String&gt; attrs) {<a name="line.112"></a>
116<FONT color="green">113</FONT>          return null;<a name="line.113"></a>
117<FONT color="green">114</FONT>        }<a name="line.114"></a>
118<FONT color="green">115</FONT>      };<a name="line.115"></a>
119<FONT color="green">116</FONT>    <a name="line.116"></a>
120<FONT color="green">117</FONT>    }<a name="line.117"></a>
121<FONT color="green">118</FONT>    <a name="line.118"></a>
122<FONT color="green">119</FONT>    @Immutable<a name="line.119"></a>
123<FONT color="green">120</FONT>    final class JoinedElementPolicy implements ElementPolicy {<a name="line.120"></a>
124<FONT color="green">121</FONT>      final ElementPolicy first, second;<a name="line.121"></a>
125<FONT color="green">122</FONT>    <a name="line.122"></a>
126<FONT color="green">123</FONT>      JoinedElementPolicy(ElementPolicy first, ElementPolicy second) {<a name="line.123"></a>
127<FONT color="green">124</FONT>        this.first = first;<a name="line.124"></a>
128<FONT color="green">125</FONT>        this.second = second;<a name="line.125"></a>
129<FONT color="green">126</FONT>      }<a name="line.126"></a>
130<FONT color="green">127</FONT>    <a name="line.127"></a>
131<FONT color="green">128</FONT>      public @Nullable String apply(String elementName, List&lt;String&gt; attrs) {<a name="line.128"></a>
132<FONT color="green">129</FONT>        elementName = first.apply(elementName, attrs);<a name="line.129"></a>
133<FONT color="green">130</FONT>        return elementName != null ? second.apply(elementName, attrs) : null;<a name="line.130"></a>
134<FONT color="green">131</FONT>      }<a name="line.131"></a>
135<FONT color="green">132</FONT>    }<a name="line.132"></a>
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196</PRE>
197</BODY>
198</HTML>
199