mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-14 22:39:32 +08:00
chore(ngSanitize): extract $sanitize, ngBindHtml, linkyFilter into a module
Create build for other modules as well (ngResource, ngCookies):
- wrap into a function
- add license
- add version
Breaks `$sanitize` service, `ngBindHtml` directive and `linky` filter were moved to the `ngSanitize` module. Apps that depend on any of these will need to load `angular-sanitize.js` and include `ngSanitize` in their dependency list: `var myApp = angular.module('myApp', ['ngSanitize']);`
This commit is contained in:
@@ -67,39 +67,13 @@ describe('ngBind*', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('ngBindHtml', function() {
|
||||
|
||||
it('should set html', inject(function($rootScope, $compile) {
|
||||
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
||||
$rootScope.html = '<div unknown>hello</div>';
|
||||
$rootScope.$digest();
|
||||
expect(lowercase(element.html())).toEqual('<div>hello</div>');
|
||||
}));
|
||||
|
||||
|
||||
it('should reset html when value is null or undefined', inject(function($compile, $rootScope) {
|
||||
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
||||
|
||||
forEach([null, undefined, ''], function(val) {
|
||||
$rootScope.html = 'some val';
|
||||
$rootScope.$digest();
|
||||
expect(lowercase(element.html())).toEqual('some val');
|
||||
|
||||
$rootScope.html = val;
|
||||
$rootScope.$digest();
|
||||
expect(lowercase(element.html())).toEqual('');
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('ngBindHtmlUnsafe', function() {
|
||||
|
||||
it('should set unsafe html', inject(function($rootScope, $compile) {
|
||||
element = $compile('<div ng-bind-html-unsafe="html"></div>')($rootScope);
|
||||
$rootScope.html = '<div onclick="">hello</div>';
|
||||
$rootScope.$digest();
|
||||
expect(lowercase(element.html())).toEqual('<div onclick="">hello</div>');
|
||||
expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -153,32 +153,6 @@ describe('filters', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('linky', function() {
|
||||
var linky;
|
||||
|
||||
beforeEach(inject(function($filter){
|
||||
linky = $filter('linky')
|
||||
}));
|
||||
|
||||
it('should do basic filter', function() {
|
||||
expect(linky("http://ab/ (http://a/) <http://a/> http://1.2/v:~-123. c")).
|
||||
toEqual('<a href="http://ab/">http://ab/</a> ' +
|
||||
'(<a href="http://a/">http://a/</a>) ' +
|
||||
'<<a href="http://a/">http://a/</a>> ' +
|
||||
'<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c');
|
||||
expect(linky(undefined)).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should handle mailto:', function() {
|
||||
expect(linky("mailto:me@example.com")).
|
||||
toEqual('<a href="mailto:me@example.com">me@example.com</a>');
|
||||
expect(linky("me@example.com")).
|
||||
toEqual('<a href="mailto:me@example.com">me@example.com</a>');
|
||||
expect(linky("send email to me@example.com, but")).
|
||||
toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but');
|
||||
});
|
||||
});
|
||||
|
||||
describe('date', function() {
|
||||
|
||||
var morning = new angular.mock.TzDate(+5, '2010-09-03T12:05:08.000Z'); //7am
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('HTML', function() {
|
||||
|
||||
var expectHTML;
|
||||
|
||||
beforeEach(inject(function($sanitize) {
|
||||
expectHTML = function(html){
|
||||
return expect($sanitize(html));
|
||||
};
|
||||
}));
|
||||
|
||||
describe('htmlParser', function() {
|
||||
var handler, start, text;
|
||||
beforeEach(function() {
|
||||
handler = {
|
||||
start: function(tag, attrs, unary){
|
||||
start = {
|
||||
tag: tag,
|
||||
attrs: attrs,
|
||||
unary: unary
|
||||
};
|
||||
// Since different browsers handle newlines differenttly we trim
|
||||
// so that it is easier to write tests.
|
||||
forEach(attrs, function(value, key){
|
||||
attrs[key] = trim(value);
|
||||
});
|
||||
},
|
||||
chars: function(text_){
|
||||
text = text_;
|
||||
},
|
||||
end:function(tag) {
|
||||
expect(tag).toEqual(start.tag);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should parse basic format', function() {
|
||||
htmlParser('<tag attr="value">text</tag>', handler);
|
||||
expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false});
|
||||
expect(text).toEqual('text');
|
||||
});
|
||||
|
||||
it('should parse newlines in tags', function() {
|
||||
htmlParser('<\ntag\n attr="value"\n>text<\n/\ntag\n>', handler);
|
||||
expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false});
|
||||
expect(text).toEqual('text');
|
||||
});
|
||||
|
||||
it('should parse newlines in attributes', function() {
|
||||
htmlParser('<tag attr="\nvalue\n">text</tag>', handler);
|
||||
expect(start).toEqual({tag:'tag', attrs:{attr:'value'}, unary:false});
|
||||
expect(text).toEqual('text');
|
||||
});
|
||||
|
||||
it('should parse namespace', function() {
|
||||
htmlParser('<ns:t-a-g ns:a-t-t-r="\nvalue\n">text</ns:t-a-g>', handler);
|
||||
expect(start).toEqual({tag:'ns:t-a-g', attrs:{'ns:a-t-t-r':'value'}, unary:false});
|
||||
expect(text).toEqual('text');
|
||||
});
|
||||
|
||||
it('should parse empty value attribute of node', function() {
|
||||
htmlParser('<OPTION selected value="">abc</OPTION>', handler);
|
||||
expect(start).toEqual({tag:'option', attrs:{selected:'', value:''}, unary:false});
|
||||
expect(text).toEqual('abc');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
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 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 entities', function() {
|
||||
var everything = '<div rel="!@#$%^&*()_+-={}[]:";\'<>?,./`~ ħ">' +
|
||||
'!@#$%^&*()_+-={}[]:";\'<>?,./`~ ħ</div>';
|
||||
expectHTML(everything).toEqual(everything);
|
||||
});
|
||||
|
||||
it('should handle improper html', function() {
|
||||
expectHTML('< div rel="</div>" alt=abc dir=\'"\' >text< /div>').
|
||||
toEqual('<div rel="</div>" alt="abc" dir=""">text</div>');
|
||||
});
|
||||
|
||||
it('should handle improper html2', function() {
|
||||
expectHTML('< div rel="</div>" / >').
|
||||
toEqual('<div rel="</div>"/>');
|
||||
});
|
||||
|
||||
it('should ignore back slash as escape', function() {
|
||||
expectHTML('<img alt="xxx\\" title="><script>....">').
|
||||
toEqual('<img alt="xxx\\" title="><script>...."/>');
|
||||
});
|
||||
|
||||
it('should ignore object attributes', function() {
|
||||
expectHTML('<a constructor="hola">:)</a>').
|
||||
toEqual('<a>:)</a>');
|
||||
expectHTML('<constructor constructor="hola">:)</constructor>').
|
||||
toEqual('');
|
||||
});
|
||||
|
||||
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', {rel:'123'}, false);
|
||||
writer.chars('in');
|
||||
writer.end('div');
|
||||
writer.chars('after');
|
||||
|
||||
expect(html).toEqual('before<div rel="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 escape IE script', function() {
|
||||
writer.chars('&<>{}');
|
||||
expect(html).toEqual('&<>{}');
|
||||
});
|
||||
|
||||
it('should escape attributes', function() {
|
||||
writer.start('div', {rel:'!@#$%^&*()_+-={}[]:";\'<>?,./`~ \n\0\r\u0127'});
|
||||
expect(html).toEqual('<div rel="!@#$%^&*()_+-={}[]:";\'<>?,./`~ � ħ">');
|
||||
});
|
||||
|
||||
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('explicitly dissallow', function() {
|
||||
it('should not allow attributes', function() {
|
||||
writer.start('div', {id:'a', name:'a', style:'a'});
|
||||
expect(html).toEqual('<div>');
|
||||
});
|
||||
|
||||
it('should not allow tags', function() {
|
||||
function tag(name) {
|
||||
writer.start(name, {});
|
||||
writer.end(name);
|
||||
}
|
||||
tag('frameset');
|
||||
tag('frame');
|
||||
tag('form');
|
||||
tag('param');
|
||||
tag('object');
|
||||
tag('embed');
|
||||
tag('textarea');
|
||||
tag('input');
|
||||
tag('button');
|
||||
tag('option');
|
||||
tag('select');
|
||||
tag('script');
|
||||
tag('style');
|
||||
tag('link');
|
||||
tag('base');
|
||||
tag('basefont');
|
||||
expect(html).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isUri', function() {
|
||||
|
||||
function isUri(value) {
|
||||
return value.match(URI_REGEXP);
|
||||
}
|
||||
|
||||
it('should be URI', function() {
|
||||
expect(isUri('http://abc')).toBeTruthy();
|
||||
expect(isUri('https://abc')).toBeTruthy();
|
||||
expect(isUri('ftp://abc')).toBeTruthy();
|
||||
expect(isUri('mailto:me@example.com')).toBeTruthy();
|
||||
expect(isUri('#anchor')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not be UIR', function() {
|
||||
expect(isUri('')).toBeFalsy();
|
||||
expect(isUri('javascript:alert')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('javascript URL attribute', function() {
|
||||
beforeEach(function() {
|
||||
this.addMatchers({
|
||||
toBeValidUrl: function() {
|
||||
return URI_REGEXP.exec(this.actual);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should ignore javascript:', function() {
|
||||
expect('JavaScript:abc').not.toBeValidUrl();
|
||||
expect(' \n Java\n Script:abc').not.toBeValidUrl();
|
||||
expect('http://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();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user