Skip to content

Commit

Permalink
feat(ngSanitize): add $sanitizeExt factory
Browse files Browse the repository at this point in the history
Add $sanitizeExt factory to allow extenstion of the $sanitize element
and
attribute whitelists. This allows for unsupported, standard elements and
attributes, as well as custom elements and attributes.

Closes angular#5900
  • Loading branch information
Brady Isom committed Apr 25, 2014
1 parent e19dbc7 commit 228b094
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
51 changes: 49 additions & 2 deletions src/ngSanitize/sanitize.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
* browser, won't make it through the sanitizer.
* The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
* `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
* `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}
* as well as the functions `addSafeElements` and `addSafeAttributes` of
* {@link ngSanitize.$sanitizeExt `$sanitizeExt`}.
*
* @param {string} html Html input.
* @returns {string} Sanitized html.
Expand Down Expand Up @@ -201,6 +203,12 @@ var validElements = angular.extend({},
inlineElements,
optionalEndTagElements);

//Unsupported elements:
// audio,base,body,button,canvas,command,data,datalist,details,dialog,embed,
// fieldset,form,head,html,iframe,input,keygen,legend,link,meta,meter,
// noscript,object,optgroup,option,output,param,progress,select,source,
// summary,textarea,title,track,video

//Attributes that have href and hence need to be sanitized
var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
var validAttrs = angular.extend({}, uriAttrs, makeMap(
Expand All @@ -216,6 +224,43 @@ function makeMap(str) {
return obj;
}

/**
* @ngdoc object
* @name ngSanitize.$sanitizeExt
*
* @description
* Extends the safe token whitelists used by the {@link ngSanitize.$sanitize `$sanitize`} service.
*/
function $SanitizeExtFactory() {
return {
/**
* @ngdoc method
* @name ngSanitize.$sanitizeExt#addSafeElements
* @methodOf ngSanitize.$sanitizeExt
*
* @description
* Extends the default HTML element whitelist used during sanitization.
* @param {string} elements Comma-separated list of tag names to add to the whitelist.
*/
addSafeElements: function(elements) {
var map = makeMap(elements);
angular.extend(blockElements, map);
angular.extend(validElements, map);
},
/**
* @ngdoc method
* @name ngSanitize.$sanitizeExt#addSafeAttributes
* @methodOf ngSanitize.$sanitizeExt
*
* @description
* Extends the default attribute whitelist used during sanitization.
* @param {string} attrs Comma-separated list of attribute names to add to the whitelist.
*/
addSafeAttributes: function(attrs) {
angular.extend(validAttrs, makeMap(attrs));
}
};
}

/**
* @example
Expand Down Expand Up @@ -464,4 +509,6 @@ function htmlSanitizeWriter(buf, uriValidator){


// define ngSanitize module and register $sanitize service
angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
angular.module('ngSanitize', [])
.provider('$sanitize', $SanitizeProvider)
.factory('$sanitizeExt', $SanitizeExtFactory);
21 changes: 21 additions & 0 deletions test/ngSanitize/sanitizeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,27 @@ describe('HTML', function() {
expect(sanitizeText('a<div>&</div>c')).toEqual('a&lt;div&gt;&amp;&lt;/div&gt;c');
});
});

describe('sanitizeExt', function() {
beforeEach(function() {
var sanitizeExt;
inject(function($sanitizeExt) {
sanitizeExt = $sanitizeExt;
});
sanitizeExt.addSafeElements('audio,video,a:custom');
sanitizeExt.addSafeAttributes('autoplay,custom');
});

it('should extend valid tags', function() {
expectHTML('a<audio src="abc"></audio>c').toEqual('a<audio src="abc"></audio>c');
expectHTML('a<video src="abc"></video>c').toEqual('a<video src="abc"></video>c');
expectHTML('a<a:custom>b</a:custom>c').toEqual('a<a:custom>b</a:custom>c');
});
it('should extend valid attributes', function() {
expectHTML('a<div autoplay="true" custom="y" class="b" unknown="x"></div>c').toEqual('a<div autoplay="true" custom="y" class="b"></div>c');
});

});
});

describe('decodeEntities', function() {
Expand Down

0 comments on commit 228b094

Please sign in to comment.