@@ -46,6 +46,8 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
46
46
* it into the returned string, however, since our parser is more strict than a typical browser
47
47
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
48
48
* browser, won't make it through the sanitizer.
49
+ * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
50
+ * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
49
51
*
50
52
* @param {string } html Html input.
51
53
* @returns {string } Sanitized html.
@@ -128,11 +130,24 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
128
130
</doc:scenario>
129
131
</doc:example>
130
132
*/
131
- var $sanitize = function ( html ) {
133
+ function $SanitizeProvider ( ) {
134
+ this . $get = [ '$$sanitizeUri' , function ( $$sanitizeUri ) {
135
+ return function ( html ) {
136
+ var buf = [ ] ;
137
+ htmlParser ( html , htmlSanitizeWriter ( buf , function ( uri , isImage ) {
138
+ return ! / ^ u n s a f e / . test ( $$sanitizeUri ( uri , isImage ) ) ;
139
+ } ) ) ;
140
+ return buf . join ( '' ) ;
141
+ } ;
142
+ } ] ;
143
+ }
144
+
145
+ function sanitizeText ( chars ) {
132
146
var buf = [ ] ;
133
- htmlParser ( html , htmlSanitizeWriter ( buf ) ) ;
134
- return buf . join ( '' ) ;
135
- } ;
147
+ var writer = htmlSanitizeWriter ( buf , angular . noop ) ;
148
+ writer . chars ( chars ) ;
149
+ return buf . join ( '' ) ;
150
+ }
136
151
137
152
138
153
// Regular Expressions for parsing tags and attributes
@@ -145,7 +160,6 @@ var START_TAG_REGEXP =
145
160
COMMENT_REGEXP = / < ! - - ( .* ?) - - > / g,
146
161
DOCTYPE_REGEXP = / < ! D O C T Y P E ( [ ^ > ] * ?) > / i,
147
162
CDATA_REGEXP = / < ! \[ C D A T A \[ ( .* ?) ] ] > / g,
148
- URI_REGEXP = / ^ ( ( f t p | h t t p s ? ) : \/ \/ | m a i l t o : | t e l : | # ) / i,
149
163
// Match everything outside of normal chars and " (quote character)
150
164
NON_ALPHANUMERIC_REGEXP = / ( [ ^ \# - ~ | | ! ] ) / g;
151
165
@@ -353,8 +367,18 @@ function htmlParser( html, handler ) {
353
367
*/
354
368
var hiddenPre = document . createElement ( "pre" ) ;
355
369
function decodeEntities ( value ) {
356
- hiddenPre . innerHTML = value . replace ( / < / g, "<" ) ;
357
- return hiddenPre . innerText || hiddenPre . textContent || '' ;
370
+ if ( ! value ) {
371
+ return '' ;
372
+ }
373
+ // Note: IE8 does not preserve spaces at the start/end of innerHTML
374
+ var spaceRe = / ^ ( \s * ) ( [ \s \S ] * ?) ( \s * ) $ / ;
375
+ var parts = spaceRe . exec ( value ) ;
376
+ parts [ 0 ] = '' ;
377
+ if ( parts [ 2 ] ) {
378
+ hiddenPre . innerHTML = parts [ 2 ] . replace ( / < / g, "<" ) ;
379
+ parts [ 2 ] = hiddenPre . innerText || hiddenPre . textContent ;
380
+ }
381
+ return parts . join ( '' ) ;
358
382
}
359
383
360
384
/**
@@ -384,7 +408,7 @@ function encodeEntities(value) {
384
408
* comment: function(text) {}
385
409
* }
386
410
*/
387
- function htmlSanitizeWriter ( buf ) {
411
+ function htmlSanitizeWriter ( buf , uriValidator ) {
388
412
var ignore = false ;
389
413
var out = angular . bind ( buf , buf . push ) ;
390
414
return {
@@ -398,7 +422,9 @@ function htmlSanitizeWriter(buf){
398
422
out ( tag ) ;
399
423
angular . forEach ( attrs , function ( value , key ) {
400
424
var lkey = angular . lowercase ( key ) ;
401
- if ( validAttrs [ lkey ] === true && ( uriAttrs [ lkey ] !== true || value . match ( URI_REGEXP ) ) ) {
425
+ var isImage = ( tag === 'img' && lkey === 'src' ) || ( lkey === 'background' ) ;
426
+ if ( validAttrs [ lkey ] === true &&
427
+ ( uriAttrs [ lkey ] !== true || uriValidator ( value , isImage ) ) ) {
402
428
out ( ' ' ) ;
403
429
out ( key ) ;
404
430
out ( '="' ) ;
@@ -430,4 +456,4 @@ function htmlSanitizeWriter(buf){
430
456
431
457
432
458
// define ngSanitize module and register $sanitize service
433
- angular . module ( 'ngSanitize' , [ ] ) . value ( '$sanitize' , $sanitize ) ;
459
+ angular . module ( 'ngSanitize' , [ ] ) . provider ( '$sanitize' , $SanitizeProvider ) ;
0 commit comments