@@ -15,6 +15,7 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
15
15
var bind ;
16
16
var extend ;
17
17
var forEach ;
18
+ var isArray ;
18
19
var isDefined ;
19
20
var lowercase ;
20
21
var noop ;
@@ -145,9 +146,11 @@ var htmlSanitizeWriter;
145
146
* Creates and configures {@link $sanitize} instance.
146
147
*/
147
148
function $SanitizeProvider ( ) {
149
+ var hasBeenInstantiated = false ;
148
150
var svgEnabled = false ;
149
151
150
152
this . $get = [ '$$sanitizeUri' , function ( $$sanitizeUri ) {
153
+ hasBeenInstantiated = true ;
151
154
if ( svgEnabled ) {
152
155
extend ( validElements , svgElements ) ;
153
156
}
@@ -188,7 +191,7 @@ function $SanitizeProvider() {
188
191
* </div>
189
192
*
190
193
* @param {boolean= } flag Enable or disable SVG support in the sanitizer.
191
- * @returns {boolean|ng. $sanitizeProvider } Returns the currently configured value if called
194
+ * @returns {boolean|$sanitizeProvider } Returns the currently configured value if called
192
195
* without an argument or self for chaining otherwise.
193
196
*/
194
197
this . enableSvg = function ( enableSvg ) {
@@ -200,13 +203,113 @@ function $SanitizeProvider() {
200
203
}
201
204
} ;
202
205
206
+
207
+ /**
208
+ * @ngdoc method
209
+ * @name $sanitizeProvider#addValidElements
210
+ * @kind function
211
+ *
212
+ * @description
213
+ * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe
214
+ * and are not stripped off during sanitization. You can extend the following lists of elements:
215
+ *
216
+ * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML
217
+ * elements. HTML elements considered safe will not be removed during sanitization. All other
218
+ * elements will be stripped off.
219
+ *
220
+ * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as
221
+ * "void elements" (similar to HTML
222
+ * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These
223
+ * elements have no end tag and cannot have content.
224
+ *
225
+ * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only
226
+ * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for
227
+ * `$sanitize`.
228
+ *
229
+ * <div class="alert alert-info">
230
+ * This method must be called during the {@link angular.Module#config config} phase. Once the
231
+ * `$sanitize` service has been instantiated, this method has no effect.
232
+ * </div>
233
+ *
234
+ * <div class="alert alert-warning">
235
+ * Keep in mind that extending the built-in lists of elements may expose your app to XSS or
236
+ * other vulnerabilities. Be very mindful of the elements you add.
237
+ * </div>
238
+ *
239
+ * @param {Array<String>|Object } elements - A list of valid HTML elements or an object with one or
240
+ * more of the following properties:
241
+ * - **htmlElements** - `{Array<String>}` - A list of elements to extend the current list of
242
+ * HTML elements.
243
+ * - **htmlVoidElements** - `{Array<String>}` - A list of elements to extend the current list of
244
+ * void HTML elements; i.e. elements that do not have an end tag.
245
+ * - **svgElements** - `{Array<String>}` - A list of elements to extend the current list of SVG
246
+ * elements. The list of SVG elements is only taken into account if SVG is
247
+ * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`.
248
+ *
249
+ * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`.
250
+ *
251
+ * @return {$sanitizeProvider } Returns self for chaining.
252
+ */
253
+ this . addValidElements = function ( elements ) {
254
+ if ( ! hasBeenInstantiated ) {
255
+ if ( isArray ( elements ) ) {
256
+ elements = { htmlElements : elements } ;
257
+ }
258
+
259
+ addElementsTo ( svgElements , elements . svgElements ) ;
260
+ addElementsTo ( voidElements , elements . htmlVoidElements ) ;
261
+ addElementsTo ( validElements , elements . htmlVoidElements ) ;
262
+ addElementsTo ( validElements , elements . htmlElements ) ;
263
+ }
264
+
265
+ return this ;
266
+ } ;
267
+
268
+
269
+ /**
270
+ * @ngdoc method
271
+ * @name $sanitizeProvider#addValidAttrs
272
+ * @kind function
273
+ *
274
+ * @description
275
+ * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are
276
+ * not stripped off during sanitization.
277
+ *
278
+ * **Note**:
279
+ * The new attributes will not be treated as URI attributes, which means their values will not be
280
+ * sanitized as URIs using `$compileProvider`'s
281
+ * {@link ng.$compileProvider#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and
282
+ * {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}.
283
+ *
284
+ * <div class="alert alert-info">
285
+ * This method must be called during the {@link angular.Module#config config} phase. Once the
286
+ * `$sanitize` service has been instantiated, this method has no effect.
287
+ * </div>
288
+ *
289
+ * <div class="alert alert-warning">
290
+ * Keep in mind that extending the built-in list of attributes may expose your app to XSS or
291
+ * other vulnerabilities. Be very mindful of the attributes you add.
292
+ * </div>
293
+ *
294
+ * @param {Array<String> } attrs - A list of valid attributes.
295
+ *
296
+ * @returns {$sanitizeProvider } Returns self for chaining.
297
+ */
298
+ this . addValidAttrs = function ( attrs ) {
299
+ if ( ! hasBeenInstantiated ) {
300
+ extend ( validAttrs , arrayToMap ( attrs , true ) ) ;
301
+ }
302
+ return this ;
303
+ } ;
304
+
203
305
//////////////////////////////////////////////////////////////////////////////////////////////////
204
306
// Private stuff
205
307
//////////////////////////////////////////////////////////////////////////////////////////////////
206
308
207
309
bind = angular . bind ;
208
310
extend = angular . extend ;
209
311
forEach = angular . forEach ;
312
+ isArray = angular . isArray ;
210
313
isDefined = angular . isDefined ;
211
314
lowercase = angular . lowercase ;
212
315
noop = angular . noop ;
@@ -231,36 +334,36 @@ function $SanitizeProvider() {
231
334
232
335
// Safe Void Elements - HTML5
233
336
// http://dev.w3.org/html5/spec/Overview.html#void-elements
234
- var voidElements = toMap ( 'area,br,col,hr,img,wbr' ) ;
337
+ var voidElements = stringToMap ( 'area,br,col,hr,img,wbr' ) ;
235
338
236
339
// Elements that you can, intentionally, leave open (and which close themselves)
237
340
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
238
- var optionalEndTagBlockElements = toMap ( 'colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr' ) ,
239
- optionalEndTagInlineElements = toMap ( 'rp,rt' ) ,
341
+ var optionalEndTagBlockElements = stringToMap ( 'colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr' ) ,
342
+ optionalEndTagInlineElements = stringToMap ( 'rp,rt' ) ,
240
343
optionalEndTagElements = extend ( { } ,
241
344
optionalEndTagInlineElements ,
242
345
optionalEndTagBlockElements ) ;
243
346
244
347
// Safe Block Elements - HTML5
245
- var blockElements = extend ( { } , optionalEndTagBlockElements , toMap ( 'address,article,' +
348
+ var blockElements = extend ( { } , optionalEndTagBlockElements , stringToMap ( 'address,article,' +
246
349
'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
247
350
'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul' ) ) ;
248
351
249
352
// Inline Elements - HTML5
250
- var inlineElements = extend ( { } , optionalEndTagInlineElements , toMap ( 'a,abbr,acronym,b,' +
353
+ var inlineElements = extend ( { } , optionalEndTagInlineElements , stringToMap ( 'a,abbr,acronym,b,' +
251
354
'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
252
355
'samp,small,span,strike,strong,sub,sup,time,tt,u,var' ) ) ;
253
356
254
357
// SVG Elements
255
358
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
256
359
// Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
257
360
// They can potentially allow for arbitrary javascript to be executed. See #11290
258
- var svgElements = toMap ( 'circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
361
+ var svgElements = stringToMap ( 'circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
259
362
'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
260
363
'radialGradient,rect,stop,svg,switch,text,title,tspan' ) ;
261
364
262
365
// Blocked Elements (will be stripped)
263
- var blockedElements = toMap ( 'script,style' ) ;
366
+ var blockedElements = stringToMap ( 'script,style' ) ;
264
367
265
368
var validElements = extend ( { } ,
266
369
voidElements ,
@@ -269,17 +372,17 @@ function $SanitizeProvider() {
269
372
optionalEndTagElements ) ;
270
373
271
374
//Attributes that have href and hence need to be sanitized
272
- var uriAttrs = toMap ( 'background,cite,href,longdesc,src,xlink:href,xml:base' ) ;
375
+ var uriAttrs = stringToMap ( 'background,cite,href,longdesc,src,xlink:href,xml:base' ) ;
273
376
274
- var htmlAttrs = toMap ( 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
377
+ var htmlAttrs = stringToMap ( 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
275
378
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
276
379
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
277
380
'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
278
381
'valign,value,vspace,width' ) ;
279
382
280
383
// SVG attributes (without "id" and "name" attributes)
281
384
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
282
- var svgAttrs = toMap ( 'accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
385
+ var svgAttrs = stringToMap ( 'accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
283
386
'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
284
387
'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
285
388
'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
@@ -300,14 +403,24 @@ function $SanitizeProvider() {
300
403
svgAttrs ,
301
404
htmlAttrs ) ;
302
405
303
- function toMap ( str , lowercaseKeys ) {
304
- var obj = { } , items = str . split ( ',' ) , i ;
406
+ function stringToMap ( str , lowercaseKeys ) {
407
+ return arrayToMap ( str . split ( ',' ) , lowercaseKeys ) ;
408
+ }
409
+
410
+ function arrayToMap ( items , lowercaseKeys ) {
411
+ var obj = { } , i ;
305
412
for ( i = 0 ; i < items . length ; i ++ ) {
306
413
obj [ lowercaseKeys ? lowercase ( items [ i ] ) : items [ i ] ] = true ;
307
414
}
308
415
return obj ;
309
416
}
310
417
418
+ function addElementsTo ( elementsMap , newElements ) {
419
+ if ( newElements && newElements . length ) {
420
+ extend ( elementsMap , arrayToMap ( newElements ) ) ;
421
+ }
422
+ }
423
+
311
424
/**
312
425
* Create an inert document that contains the dirty HTML that needs sanitizing
313
426
* Depending upon browser support we use one of three strategies for doing this.
0 commit comments