@@ -46,6 +46,8 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
4646 * it into the returned string, however, since our parser is more strict than a typical browser
4747 * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
4848 * 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`}.
4951 *
5052 * @param {string } html Html input.
5153 * @returns {string } Sanitized html.
@@ -128,11 +130,24 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
128130 </doc:scenario>
129131 </doc:example>
130132 */
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 ) {
132146 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+ }
136151
137152
138153// Regular Expressions for parsing tags and attributes
@@ -145,7 +160,6 @@ var START_TAG_REGEXP =
145160 COMMENT_REGEXP = / < ! - - ( .* ?) - - > / g,
146161 DOCTYPE_REGEXP = / < ! D O C T Y P E ( [ ^ > ] * ?) > / i,
147162 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,
149163 // Match everything outside of normal chars and " (quote character)
150164 NON_ALPHANUMERIC_REGEXP = / ( [ ^ \# - ~ | | ! ] ) / g;
151165
@@ -353,8 +367,18 @@ function htmlParser( html, handler ) {
353367 */
354368var hiddenPre = document . createElement ( "pre" ) ;
355369function 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 ( '' ) ;
358382}
359383
360384/**
@@ -384,7 +408,7 @@ function encodeEntities(value) {
384408 * comment: function(text) {}
385409 * }
386410 */
387- function htmlSanitizeWriter ( buf ) {
411+ function htmlSanitizeWriter ( buf , uriValidator ) {
388412 var ignore = false ;
389413 var out = angular . bind ( buf , buf . push ) ;
390414 return {
@@ -398,7 +422,9 @@ function htmlSanitizeWriter(buf){
398422 out ( tag ) ;
399423 angular . forEach ( attrs , function ( value , key ) {
400424 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 ) ) ) {
402428 out ( ' ' ) ;
403429 out ( key ) ;
404430 out ( '="' ) ;
@@ -430,4 +456,4 @@ function htmlSanitizeWriter(buf){
430456
431457
432458// define ngSanitize module and register $sanitize service
433- angular . module ( 'ngSanitize' , [ ] ) . value ( '$sanitize' , $sanitize ) ;
459+ angular . module ( 'ngSanitize' , [ ] ) . provider ( '$sanitize' , $SanitizeProvider ) ;
0 commit comments