diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/AngularSpec.js | 11 | ||||
| -rw-r--r-- | test/directivesSpec.js | 9 | ||||
| -rw-r--r-- | test/sanitizerSpec.js | 154 | ||||
| -rw-r--r-- | test/testabilityPatch.js | 5 |
4 files changed, 176 insertions, 3 deletions
diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 8c7249d9..b60b7bd8 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -13,6 +13,15 @@ describe('Angular', function(){ }); }); +describe('case', function(){ + it('should change case', function(){ + expect(lowercase('ABC90')).toEqual('abc90'); + expect(manualLowercase('ABC90')).toEqual('abc90'); + expect(uppercase('abc90')).toEqual('ABC90'); + expect(manualUppercase('abc90')).toEqual('ABC90'); + }); +}); + describe("copy", function(){ it("should return same object", function (){ var obj = {}; @@ -115,7 +124,7 @@ describe('toKeyValue', function() { toEqual('escaped%20key=escaped%20value'); expect(toKeyValue({emptyKey: ''})).toEqual('emptyKey='); }); - + it('should parse true values into flags', function() { expect(toKeyValue({flag1: true, key: 'value', flag2: true})).toEqual('flag1&key=value&flag2'); }); diff --git a/test/directivesSpec.js b/test/directivesSpec.js index 0e99a63f..34dcbf8d 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -50,11 +50,18 @@ describe("directives", function(){ it('should set html', function() { var scope = compile('<div ng:bind="html|html"></div>'); - scope.html = '<div>hello</div>'; + scope.html = '<div unknown>hello</div>'; scope.$eval(); expect(lowercase(element.html())).toEqual('<div>hello</div>'); }); + it('should set unsafe html', function() { + var scope = compile('<div ng:bind="html|html:\'unsafe\'"></div>'); + scope.html = '<div onclick="">hello</div>'; + scope.$eval(); + expect(lowercase(element.html())).toEqual('<div onclick="">hello</div>'); + }); + it('should set element element', function() { angularFilter.myElement = function() { return jqLite('<a>hello</a>'); diff --git a/test/sanitizerSpec.js b/test/sanitizerSpec.js new file mode 100644 index 00000000..4e1ff355 --- /dev/null +++ b/test/sanitizerSpec.js @@ -0,0 +1,154 @@ +describe('HTML', function(){ + + function expectHTML(html) { + return expect(new HTML(html).get()); + } + + it('should echo html', function(){ + expectHTML('hello<b class="1\'23" align=\'""\'>world</b>.'). + toEqual('hello<b class="1\'23" align="""">world</b>.'); + }); + + it('should remove script', function(){ + expectHTML('a<SCRIPT>evil< / scrIpt >c.').toEqual('ac.'); + }); + + it('should remove nested script', function(){ + expectHTML('a< SCRIPT >A< SCRIPT >evil< / scrIpt >B< / scrIpt >c.').toEqual('ac.'); + }); + + it('should remove attrs', function(){ + expectHTML('a<div style="abc">b</div>c').toEqual('a<div>b</div>c'); + }); + + it('should remove style', function(){ + expectHTML('a<STyle>evil</stYle>c.').toEqual('ac.'); + }); + + it('should remove script and style', function(){ + expectHTML('a<STyle>evil<script></script></stYle>c.').toEqual('ac.'); + }); + + it('should remove double nested script', function(){ + expectHTML('a<SCRIPT>ev<script>evil</sCript>il</scrIpt>c.').toEqual('ac.'); + }); + + it('should remove unknown tag names', function(){ + expectHTML('a<xxx><B>b</B></xxx>c').toEqual('a<b>b</b>c'); + }); + + it('should remove unsafe value', function(){ + expectHTML('<a href="javascript:alert()">').toEqual('<a></a>'); + }); + + it('should handle self closed elements', function(){ + expectHTML('a<hr/>c').toEqual('a<hr/>c'); + }); + + it('should handle namespace', function(){ + expectHTML('a<my:hr/><my:div>b</my:div>c').toEqual('abc'); + }); + + it('should handle improper html', function(){ + expectHTML('< div id="</div>" alt=abc href=\'"\' >text< /div>'). + toEqual('<div id="</div>" alt="abc" href=""">text</div>'); + }); + + it('should handle improper html2', function(){ + expectHTML('< div id="</div>" / >'). + toEqual('<div id="</div>"/>'); + }); + + describe('htmlSanitizerWriter', function(){ + var writer, html; + beforeEach(function(){ + html = ''; + writer = htmlSanitizeWriter({push:function(text){html+=text;}}); + }); + + it('should write basic HTML', function(){ + writer.chars('before'); + writer.start('div', {id:'123'}, false); + writer.chars('in'); + writer.end('div'); + writer.chars('after'); + + expect(html).toEqual('before<div id="123">in</div>after'); + }); + + it('should escape text nodes', function(){ + writer.chars('a<div>&</div>c'); + expect(html).toEqual('a<div>&</div>c'); + }); + + it('should not double escape entities', function(){ + writer.chars(' ><'); + expect(html).toEqual(' ><'); + }); + + it('should escape IE script', function(){ + writer.chars('&{}'); + expect(html).toEqual('&{}'); + }); + + it('should escape attributes', function(){ + writer.start('div', {id:'\"\'<>'}); + expect(html).toEqual('<div id=""\'<>">'); + }); + + it('should ignore missformed elements', function(){ + writer.start('d>i&v', {}); + expect(html).toEqual(''); + }); + + it('should ignore unknown attributes', function(){ + writer.start('div', {unknown:""}); + expect(html).toEqual('<div>'); + }); + + describe('javascript URL attribute', function(){ + beforeEach(function(){ + this.addMatchers({ + toBeValidUrl: function(){ + return !isJavaScriptUrl(this.actual); + } + }); + }); + + it('should ignore javascript:', function(){ + expect('JavaScript:abc').not.toBeValidUrl(); + expect(' \n Java\n Script:abc').not.toBeValidUrl(); + expect('JavaScript/my.js').toBeValidUrl(); + }); + + it('should ignore dec encoded javascript:', function(){ + expect('javascript:').not.toBeValidUrl(); + expect('javascript:').not.toBeValidUrl(); + expect('j avascript:').not.toBeValidUrl(); + }); + + it('should ignore decimal with leading 0 encodede javascript:', function(){ + expect('javascript:').not.toBeValidUrl(); + expect('j avascript:').not.toBeValidUrl(); + expect('j avascript:').not.toBeValidUrl(); + }); + + it('should ignore hex encoded javascript:', function(){ + expect('javascript:').not.toBeValidUrl(); + expect('javascript:').not.toBeValidUrl(); + expect('j avascript:').not.toBeValidUrl(); + }); + + it('should ignore hex encoded whitespace javascript:', function(){ + expect('jav	ascript:alert("A");').not.toBeValidUrl(); + expect('jav
ascript:alert("B");').not.toBeValidUrl(); + expect('jav
 ascript:alert("C");').not.toBeValidUrl(); + expect('jav\u0000ascript:alert("D");').not.toBeValidUrl(); + expect('java\u0000\u0000script:alert("D");').not.toBeValidUrl(); + expect('  java\u0000\u0000script:alert("D");').not.toBeValidUrl(); + }); + }); + + }); + +}); diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index b4602c39..5c6eaf4d 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -85,7 +85,10 @@ function sortedHtml(element) { var html = ""; foreach(jqLite(element), function toString(node) { if (node.nodeName == "#text") { - html += escapeHtml(node.nodeValue); + html += node.nodeValue. + replace(/&(\w+[&;\W])?/g, function(match, entity){return entity?match:'&';}). + replace(/</g, '<'). + replace(/>/g, '>'); } else { html += '<' + node.nodeName.toLowerCase(); var attributes = node.attributes || []; |
