diff --git a/angularFiles.js b/angularFiles.js index 05f93bf8..1070299f 100644 --- a/angularFiles.js +++ b/angularFiles.js @@ -6,7 +6,6 @@ angularFiles = { 'src/JSON.js', 'src/Injector.js', 'src/Resource.js', - 'src/sanitizer.js', 'src/jqLite.js', 'src/apis.js', 'src/service/anchorScroll.js', @@ -34,6 +33,7 @@ angularFiles = { 'src/service/route.js', 'src/service/routeParams.js', 'src/service/scope.js', + 'src/service/sanitize.js', 'src/service/sniffer.js', 'src/service/window.js', 'src/service/http.js', diff --git a/src/sanitizer.js b/src/service/sanitize.js similarity index 71% rename from src/sanitizer.js rename to src/service/sanitize.js index 207b1039..0d5c74af 100644 --- a/src/sanitizer.js +++ b/src/service/sanitize.js @@ -16,6 +16,102 @@ * */ + + +/** + * @ngdoc service + * @name angular.module.ng.$sanitize + * @function + * + * @description + * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are + * then serialized back to properly escaped html string. This means that no unsafe input can make + * it into the returned string, however, since our parser is more strict than a typical browser + * 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. + * + * @param {string} html Html input. + * @returns {string} Sanitized html. + * + * @example + + + +
+ Snippet: + + + + + + + + + + + + + + + + + + + + + +
FilterSourceRendered
html filter +
<div ng:bind-html="snippet">
</div>
+
+
+
no filter
<div ng:bind-="snippet">
</div>
unsafe html filter
<div ng:bind-html-unsafe="snippet">
</div>
+
+
+ + it('should sanitize the html snippet ', function() { + expect(using('#html-filter').element('div').html()). + toBe('

an html\nclick here\nsnippet

'); + }); + + it('should escape snippet without any filter', function() { + expect(using('#escaped-html').element('div').html()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should inline raw snippet if filtered as unsafe', function() { + expect(using('#html-unsafe-filter').element("div").html()). + toBe("

an html\n" + + "click here\n" + + "snippet

"); + }); + + it('should update', function() { + input('snippet').enter('new text'); + expect(using('#html-filter').binding('snippet')).toBe('new text'); + expect(using('#escaped-html').element('div').html()).toBe("new <b>text</b>"); + expect(using('#html-unsafe-filter').binding("snippet")).toBe('new text'); + }); +
+
+ */ + +function $SanitizeProvider() { + this.$get = valueFn(function(html) { + var buf = []; + htmlParser(html, htmlSanitizeWriter(buf)); + return buf.join(''); + }); +}; + // Regular Expressions for parsing tags and attributes var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,