├── LICENSE.md
├── README.md
├── angular-sanitize.js
├── angular-sanitize.min.js
├── angular-sanitize.min.js.map
├── bower.json
├── index.js
└── package.json
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Angular
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # packaged angular-sanitize
2 |
3 | **This package contains the legacy AngularJS (version 1.x). AngularJS support has officially ended
4 | as of January 2022.
5 | [See what ending support means](https://docs.angularjs.org/misc/version-support-status) and
6 | [read the end of life announcement](https://goo.gle/angularjs-end-of-life).**
7 |
8 | **[See `@angular/core` for the actively supported Angular](https://npmjs.com/@angular/core).**
9 |
10 | ## Install
11 |
12 | You can install this package either with `npm` or with `bower`.
13 |
14 | ### npm
15 |
16 | ```shell
17 | npm install angular-sanitize
18 | ```
19 |
20 | Then add `ngSanitize` as a dependency for your app:
21 |
22 | ```javascript
23 | angular.module('myApp', [require('angular-sanitize')]);
24 | ```
25 |
26 | ### bower
27 |
28 | ```shell
29 | bower install angular-sanitize
30 | ```
31 |
32 | Add a `
36 | ```
37 |
38 | Then add `ngSanitize` as a dependency for your app:
39 |
40 | ```javascript
41 | angular.module('myApp', ['ngSanitize']);
42 | ```
43 |
44 | ## Documentation
45 |
46 | Documentation is available on the
47 | [AngularJS docs site](http://docs.angularjs.org/api/ngSanitize).
48 |
49 | ## License
50 |
51 | The MIT License
52 |
53 | Copyright (c) 2022 Google LLC
54 |
55 | Permission is hereby granted, free of charge, to any person obtaining a copy
56 | of this software and associated documentation files (the "Software"), to deal
57 | in the Software without restriction, including without limitation the rights
58 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59 | copies of the Software, and to permit persons to whom the Software is
60 | furnished to do so, subject to the following conditions:
61 |
62 | The above copyright notice and this permission notice shall be included in
63 | all copies or substantial portions of the Software.
64 |
65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
71 | THE SOFTWARE.
72 |
--------------------------------------------------------------------------------
/angular-sanitize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.3
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
9 | * Any commits to this file should be reviewed with security in mind. *
10 | * Changes to this file can potentially create security vulnerabilities. *
11 | * An approval from 2 Core members with history of modifying *
12 | * this file is required. *
13 | * *
14 | * Does the change somehow allow for arbitrary javascript to be executed? *
15 | * Or allows for someone to change the prototype of built-in objects? *
16 | * Or gives undesired access to variables likes document or window? *
17 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
18 |
19 | var $sanitizeMinErr = angular.$$minErr('$sanitize');
20 | var bind;
21 | var extend;
22 | var forEach;
23 | var isArray;
24 | var isDefined;
25 | var lowercase;
26 | var noop;
27 | var nodeContains;
28 | var htmlParser;
29 | var htmlSanitizeWriter;
30 |
31 | /**
32 | * @ngdoc module
33 | * @name ngSanitize
34 | * @description
35 | *
36 | * The `ngSanitize` module provides functionality to sanitize HTML.
37 | *
38 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
39 | */
40 |
41 | /**
42 | * @ngdoc service
43 | * @name $sanitize
44 | * @kind function
45 | *
46 | * @description
47 | * Sanitizes an html string by stripping all potentially dangerous tokens.
48 | *
49 | * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a trusted URI list) are
50 | * then serialized back to a properly escaped HTML string. This means that no unsafe input can make
51 | * it into the returned string.
52 | *
53 | * The trusted URIs for URL sanitization of attribute values is configured using the functions
54 | * `aHrefSanitizationTrustedUrlList` and `imgSrcSanitizationTrustedUrlList` of {@link $compileProvider}.
55 | *
56 | * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
57 | *
58 | * @param {string} html HTML input.
59 | * @returns {string} Sanitized HTML.
60 | *
61 | * @example
62 |
63 |
64 |
76 |
77 | Snippet:
78 |
79 |
80 | Directive |
81 | How |
82 | Source |
83 | Rendered |
84 |
85 |
86 | ng-bind-html |
87 | Automatically uses $sanitize |
88 | <div ng-bind-html="snippet"> </div> |
89 | |
90 |
91 |
92 | ng-bind-html |
93 | Bypass $sanitize by explicitly trusting the dangerous value |
94 |
95 | <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
96 | </div>
97 | |
98 | |
99 |
100 |
101 | ng-bind |
102 | Automatically escapes |
103 | <div ng-bind="snippet"> </div> |
104 | |
105 |
106 |
107 |
108 |
109 |
110 | it('should sanitize the html snippet by default', function() {
111 | expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
112 | toBe('an html\nclick here\nsnippet
');
113 | });
114 |
115 | it('should inline raw snippet if bound to a trusted value', function() {
116 | expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).
117 | toBe("an html\n" +
118 | "click here\n" +
119 | "snippet
");
120 | });
121 |
122 | it('should escape snippet without any filter', function() {
123 | expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).
124 | toBe("<p style=\"color:blue\">an html\n" +
125 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
126 | "snippet</p>");
127 | });
128 |
129 | it('should update', function() {
130 | element(by.model('snippet')).clear();
131 | element(by.model('snippet')).sendKeys('new text');
132 | expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
133 | toBe('new text');
134 | expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe(
135 | 'new text');
136 | expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe(
137 | "new <b onclick=\"alert(1)\">text</b>");
138 | });
139 |
140 |
141 | */
142 |
143 |
144 | /**
145 | * @ngdoc provider
146 | * @name $sanitizeProvider
147 | * @this
148 | *
149 | * @description
150 | * Creates and configures {@link $sanitize} instance.
151 | */
152 | function $SanitizeProvider() {
153 | var hasBeenInstantiated = false;
154 | var svgEnabled = false;
155 |
156 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
157 | hasBeenInstantiated = true;
158 | if (svgEnabled) {
159 | extend(validElements, svgElements);
160 | }
161 | return function(html) {
162 | var buf = [];
163 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
164 | return !/^unsafe:/.test($$sanitizeUri(uri, isImage));
165 | }));
166 | return buf.join('');
167 | };
168 | }];
169 |
170 |
171 | /**
172 | * @ngdoc method
173 | * @name $sanitizeProvider#enableSvg
174 | * @kind function
175 | *
176 | * @description
177 | * Enables a subset of svg to be supported by the sanitizer.
178 | *
179 | *
180 | *
By enabling this setting without taking other precautions, you might expose your
181 | * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned
182 | * outside of the containing element and be rendered over other elements on the page (e.g. a login
183 | * link). Such behavior can then result in phishing incidents.
184 | *
185 | *
To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg
186 | * tags within the sanitized content:
187 | *
188 | *
189 | *
190 | *
191 | * .rootOfTheIncludedContent svg {
192 | * overflow: hidden !important;
193 | * }
194 | *
195 | *
196 | *
197 | * @param {boolean=} flag Enable or disable SVG support in the sanitizer.
198 | * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called
199 | * without an argument or self for chaining otherwise.
200 | */
201 | this.enableSvg = function(enableSvg) {
202 | if (isDefined(enableSvg)) {
203 | svgEnabled = enableSvg;
204 | return this;
205 | } else {
206 | return svgEnabled;
207 | }
208 | };
209 |
210 |
211 | /**
212 | * @ngdoc method
213 | * @name $sanitizeProvider#addValidElements
214 | * @kind function
215 | *
216 | * @description
217 | * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe
218 | * and are not stripped off during sanitization. You can extend the following lists of elements:
219 | *
220 | * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML
221 | * elements. HTML elements considered safe will not be removed during sanitization. All other
222 | * elements will be stripped off.
223 | *
224 | * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as
225 | * "void elements" (similar to HTML
226 | * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These
227 | * elements have no end tag and cannot have content.
228 | *
229 | * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only
230 | * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for
231 | * `$sanitize`.
232 | *
233 | *
234 | * This method must be called during the {@link angular.Module#config config} phase. Once the
235 | * `$sanitize` service has been instantiated, this method has no effect.
236 | *
237 | *
238 | *
239 | * Keep in mind that extending the built-in lists of elements may expose your app to XSS or
240 | * other vulnerabilities. Be very mindful of the elements you add.
241 | *
242 | *
243 | * @param {Array|Object} elements - A list of valid HTML elements or an object with one or
244 | * more of the following properties:
245 | * - **htmlElements** - `{Array}` - A list of elements to extend the current list of
246 | * HTML elements.
247 | * - **htmlVoidElements** - `{Array}` - A list of elements to extend the current list of
248 | * void HTML elements; i.e. elements that do not have an end tag.
249 | * - **svgElements** - `{Array}` - A list of elements to extend the current list of SVG
250 | * elements. The list of SVG elements is only taken into account if SVG is
251 | * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`.
252 | *
253 | * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`.
254 | *
255 | * @return {$sanitizeProvider} Returns self for chaining.
256 | */
257 | this.addValidElements = function(elements) {
258 | if (!hasBeenInstantiated) {
259 | if (isArray(elements)) {
260 | elements = {htmlElements: elements};
261 | }
262 |
263 | addElementsTo(svgElements, elements.svgElements);
264 | addElementsTo(voidElements, elements.htmlVoidElements);
265 | addElementsTo(validElements, elements.htmlVoidElements);
266 | addElementsTo(validElements, elements.htmlElements);
267 | }
268 |
269 | return this;
270 | };
271 |
272 |
273 | /**
274 | * @ngdoc method
275 | * @name $sanitizeProvider#addValidAttrs
276 | * @kind function
277 | *
278 | * @description
279 | * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are
280 | * not stripped off during sanitization.
281 | *
282 | * **Note**:
283 | * The new attributes will not be treated as URI attributes, which means their values will not be
284 | * sanitized as URIs using `$compileProvider`'s
285 | * {@link ng.$compileProvider#aHrefSanitizationTrustedUrlList aHrefSanitizationTrustedUrlList} and
286 | * {@link ng.$compileProvider#imgSrcSanitizationTrustedUrlList imgSrcSanitizationTrustedUrlList}.
287 | *
288 | *
289 | * This method must be called during the {@link angular.Module#config config} phase. Once the
290 | * `$sanitize` service has been instantiated, this method has no effect.
291 | *
292 | *
293 | *
294 | * Keep in mind that extending the built-in list of attributes may expose your app to XSS or
295 | * other vulnerabilities. Be very mindful of the attributes you add.
296 | *
297 | *
298 | * @param {Array} attrs - A list of valid attributes.
299 | *
300 | * @returns {$sanitizeProvider} Returns self for chaining.
301 | */
302 | this.addValidAttrs = function(attrs) {
303 | if (!hasBeenInstantiated) {
304 | extend(validAttrs, arrayToMap(attrs, true));
305 | }
306 | return this;
307 | };
308 |
309 | //////////////////////////////////////////////////////////////////////////////////////////////////
310 | // Private stuff
311 | //////////////////////////////////////////////////////////////////////////////////////////////////
312 |
313 | bind = angular.bind;
314 | extend = angular.extend;
315 | forEach = angular.forEach;
316 | isArray = angular.isArray;
317 | isDefined = angular.isDefined;
318 | lowercase = angular.$$lowercase;
319 | noop = angular.noop;
320 |
321 | htmlParser = htmlParserImpl;
322 | htmlSanitizeWriter = htmlSanitizeWriterImpl;
323 |
324 | nodeContains = window.Node.prototype.contains || /** @this */ function(arg) {
325 | // eslint-disable-next-line no-bitwise
326 | return !!(this.compareDocumentPosition(arg) & 16);
327 | };
328 |
329 | // Regular Expressions for parsing tags and attributes
330 | var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
331 | // Match everything outside of normal chars and " (quote character)
332 | NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g;
333 |
334 |
335 | // Good source of info about elements and attributes
336 | // http://dev.w3.org/html5/spec/Overview.html#semantics
337 | // http://simon.html5.org/html-elements
338 |
339 | // Safe Void Elements - HTML5
340 | // http://dev.w3.org/html5/spec/Overview.html#void-elements
341 | var voidElements = stringToMap('area,br,col,hr,img,wbr');
342 |
343 | // Elements that you can, intentionally, leave open (and which close themselves)
344 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags
345 | var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
346 | optionalEndTagInlineElements = stringToMap('rp,rt'),
347 | optionalEndTagElements = extend({},
348 | optionalEndTagInlineElements,
349 | optionalEndTagBlockElements);
350 |
351 | // Safe Block Elements - HTML5
352 | var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' +
353 | 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
354 | 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul'));
355 |
356 | // Inline Elements - HTML5
357 | var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' +
358 | 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
359 | 'samp,small,span,strike,strong,sub,sup,time,tt,u,var'));
360 |
361 | // SVG Elements
362 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
363 | // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
364 | // They can potentially allow for arbitrary javascript to be executed. See #11290
365 | var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
366 | 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
367 | 'radialGradient,rect,stop,svg,switch,text,title,tspan');
368 |
369 | // Blocked Elements (will be stripped)
370 | var blockedElements = stringToMap('script,style');
371 |
372 | var validElements = extend({},
373 | voidElements,
374 | blockElements,
375 | inlineElements,
376 | optionalEndTagElements);
377 |
378 | //Attributes that have href and hence need to be sanitized
379 | var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base');
380 |
381 | var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
382 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
383 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
384 | 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
385 | 'valign,value,vspace,width');
386 |
387 | // SVG attributes (without "id" and "name" attributes)
388 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
389 | var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
390 | 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
391 | 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
392 | 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
393 | 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' +
394 | 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' +
395 | 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' +
396 | 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' +
397 | 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' +
398 | 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' +
399 | 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' +
400 | 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' +
401 | 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' +
402 | 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' +
403 | 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true);
404 |
405 | var validAttrs = extend({},
406 | uriAttrs,
407 | svgAttrs,
408 | htmlAttrs);
409 |
410 | function stringToMap(str, lowercaseKeys) {
411 | return arrayToMap(str.split(','), lowercaseKeys);
412 | }
413 |
414 | function arrayToMap(items, lowercaseKeys) {
415 | var obj = {}, i;
416 | for (i = 0; i < items.length; i++) {
417 | obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true;
418 | }
419 | return obj;
420 | }
421 |
422 | function addElementsTo(elementsMap, newElements) {
423 | if (newElements && newElements.length) {
424 | extend(elementsMap, arrayToMap(newElements));
425 | }
426 | }
427 |
428 | /**
429 | * Create an inert document that contains the dirty HTML that needs sanitizing.
430 | * We use the DOMParser API by default and fall back to createHTMLDocument if DOMParser is not
431 | * available.
432 | */
433 | var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) {
434 | if (isDOMParserAvailable()) {
435 | return getInertBodyElement_DOMParser;
436 | }
437 |
438 | if (!document || !document.implementation) {
439 | throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
440 | }
441 | var inertDocument = document.implementation.createHTMLDocument('inert');
442 | var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body');
443 | return getInertBodyElement_InertDocument;
444 |
445 | function isDOMParserAvailable() {
446 | try {
447 | return !!getInertBodyElement_DOMParser('');
448 | } catch (e) {
449 | return false;
450 | }
451 | }
452 |
453 | function getInertBodyElement_DOMParser(html) {
454 | // We add this dummy element to ensure that the rest of the content is parsed as expected
455 | // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag.
456 | html = '' + html;
457 | try {
458 | var body = new window.DOMParser().parseFromString(html, 'text/html').body;
459 | body.firstChild.remove();
460 | return body;
461 | } catch (e) {
462 | return undefined;
463 | }
464 | }
465 |
466 | function getInertBodyElement_InertDocument(html) {
467 | inertBodyElement.innerHTML = html;
468 |
469 | // Support: IE 9-11 only
470 | // strip custom-namespaced attributes on IE<=11
471 | if (document.documentMode) {
472 | stripCustomNsAttrs(inertBodyElement);
473 | }
474 |
475 | return inertBodyElement;
476 | }
477 | })(window, window.document);
478 |
479 | /**
480 | * @example
481 | * htmlParser(htmlString, {
482 | * start: function(tag, attrs) {},
483 | * end: function(tag) {},
484 | * chars: function(text) {},
485 | * comment: function(text) {}
486 | * });
487 | *
488 | * @param {string} html string
489 | * @param {object} handler
490 | */
491 | function htmlParserImpl(html, handler) {
492 | if (html === null || html === undefined) {
493 | html = '';
494 | } else if (typeof html !== 'string') {
495 | html = '' + html;
496 | }
497 |
498 | var inertBodyElement = getInertBodyElement(html);
499 | if (!inertBodyElement) return '';
500 |
501 | //mXSS protection
502 | var mXSSAttempts = 5;
503 | do {
504 | if (mXSSAttempts === 0) {
505 | throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable');
506 | }
507 | mXSSAttempts--;
508 |
509 | // trigger mXSS if it is going to happen by reading and writing the innerHTML
510 | html = inertBodyElement.innerHTML;
511 | inertBodyElement = getInertBodyElement(html);
512 | } while (html !== inertBodyElement.innerHTML);
513 |
514 | var node = inertBodyElement.firstChild;
515 | while (node) {
516 | switch (node.nodeType) {
517 | case 1: // ELEMENT_NODE
518 | handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));
519 | break;
520 | case 3: // TEXT NODE
521 | handler.chars(node.textContent);
522 | break;
523 | }
524 |
525 | var nextNode;
526 | if (!(nextNode = node.firstChild)) {
527 | if (node.nodeType === 1) {
528 | handler.end(node.nodeName.toLowerCase());
529 | }
530 | nextNode = getNonDescendant('nextSibling', node);
531 | if (!nextNode) {
532 | while (nextNode == null) {
533 | node = getNonDescendant('parentNode', node);
534 | if (node === inertBodyElement) break;
535 | nextNode = getNonDescendant('nextSibling', node);
536 | if (node.nodeType === 1) {
537 | handler.end(node.nodeName.toLowerCase());
538 | }
539 | }
540 | }
541 | }
542 | node = nextNode;
543 | }
544 |
545 | while ((node = inertBodyElement.firstChild)) {
546 | inertBodyElement.removeChild(node);
547 | }
548 | }
549 |
550 | function attrToMap(attrs) {
551 | var map = {};
552 | for (var i = 0, ii = attrs.length; i < ii; i++) {
553 | var attr = attrs[i];
554 | map[attr.name] = attr.value;
555 | }
556 | return map;
557 | }
558 |
559 |
560 | /**
561 | * Escapes all potentially dangerous characters, so that the
562 | * resulting string can be safely inserted into attribute or
563 | * element text.
564 | * @param value
565 | * @returns {string} escaped text
566 | */
567 | function encodeEntities(value) {
568 | return value.
569 | replace(/&/g, '&').
570 | replace(SURROGATE_PAIR_REGEXP, function(value) {
571 | var hi = value.charCodeAt(0);
572 | var low = value.charCodeAt(1);
573 | return '' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
574 | }).
575 | replace(NON_ALPHANUMERIC_REGEXP, function(value) {
576 | return '' + value.charCodeAt(0) + ';';
577 | }).
578 | replace(//g, '>');
580 | }
581 |
582 | /**
583 | * create an HTML/XML writer which writes to buffer
584 | * @param {Array} buf use buf.join('') to get out sanitized html string
585 | * @returns {object} in the form of {
586 | * start: function(tag, attrs) {},
587 | * end: function(tag) {},
588 | * chars: function(text) {},
589 | * comment: function(text) {}
590 | * }
591 | */
592 | function htmlSanitizeWriterImpl(buf, uriValidator) {
593 | var ignoreCurrentElement = false;
594 | var out = bind(buf, buf.push);
595 | return {
596 | start: function(tag, attrs) {
597 | tag = lowercase(tag);
598 | if (!ignoreCurrentElement && blockedElements[tag]) {
599 | ignoreCurrentElement = tag;
600 | }
601 | if (!ignoreCurrentElement && validElements[tag] === true) {
602 | out('<');
603 | out(tag);
604 | forEach(attrs, function(value, key) {
605 | var lkey = lowercase(key);
606 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
607 | if (validAttrs[lkey] === true &&
608 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
609 | out(' ');
610 | out(key);
611 | out('="');
612 | out(encodeEntities(value));
613 | out('"');
614 | }
615 | });
616 | out('>');
617 | }
618 | },
619 | end: function(tag) {
620 | tag = lowercase(tag);
621 | if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {
622 | out('');
623 | out(tag);
624 | out('>');
625 | }
626 | // eslint-disable-next-line eqeqeq
627 | if (tag == ignoreCurrentElement) {
628 | ignoreCurrentElement = false;
629 | }
630 | },
631 | chars: function(chars) {
632 | if (!ignoreCurrentElement) {
633 | out(encodeEntities(chars));
634 | }
635 | }
636 | };
637 | }
638 |
639 |
640 | /**
641 | * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare
642 | * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want
643 | * to allow any of these custom attributes. This method strips them all.
644 | *
645 | * @param node Root element to process
646 | */
647 | function stripCustomNsAttrs(node) {
648 | while (node) {
649 | if (node.nodeType === window.Node.ELEMENT_NODE) {
650 | var attrs = node.attributes;
651 | for (var i = 0, l = attrs.length; i < l; i++) {
652 | var attrNode = attrs[i];
653 | var attrName = attrNode.name.toLowerCase();
654 | if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) {
655 | node.removeAttributeNode(attrNode);
656 | i--;
657 | l--;
658 | }
659 | }
660 | }
661 |
662 | var nextNode = node.firstChild;
663 | if (nextNode) {
664 | stripCustomNsAttrs(nextNode);
665 | }
666 |
667 | node = getNonDescendant('nextSibling', node);
668 | }
669 | }
670 |
671 | function getNonDescendant(propName, node) {
672 | // An element is clobbered if its `propName` property points to one of its descendants
673 | var nextNode = node[propName];
674 | if (nextNode && nodeContains.call(node, nextNode)) {
675 | throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText);
676 | }
677 | return nextNode;
678 | }
679 | }
680 |
681 | function sanitizeText(chars) {
682 | var buf = [];
683 | var writer = htmlSanitizeWriter(buf, noop);
684 | writer.chars(chars);
685 | return buf.join('');
686 | }
687 |
688 |
689 | // define ngSanitize module and register $sanitize service
690 | angular.module('ngSanitize', [])
691 | .provider('$sanitize', $SanitizeProvider)
692 | .info({ angularVersion: '1.8.3' });
693 |
694 | /**
695 | * @ngdoc filter
696 | * @name linky
697 | * @kind function
698 | *
699 | * @description
700 | * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and
701 | * plain email address links.
702 | *
703 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
704 | *
705 | * @param {string} text Input text.
706 | * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in.
707 | * @param {object|function(url)} [attributes] Add custom attributes to the link element.
708 | *
709 | * Can be one of:
710 | *
711 | * - `object`: A map of attributes
712 | * - `function`: Takes the url as a parameter and returns a map of attributes
713 | *
714 | * If the map of attributes contains a value for `target`, it overrides the value of
715 | * the target parameter.
716 | *
717 | *
718 | * @returns {string} Html-linkified and {@link $sanitize sanitized} text.
719 | *
720 | * @usage
721 |
722 | *
723 | * @example
724 |
725 |
726 |
727 | Snippet:
728 |
729 |
730 | Filter |
731 | Source |
732 | Rendered |
733 |
734 |
735 | linky filter |
736 |
737 | <div ng-bind-html="snippet | linky"> </div>
738 | |
739 |
740 |
741 | |
742 |
743 |
744 | linky target |
745 |
746 | <div ng-bind-html="snippetWithSingleURL | linky:'_blank'"> </div>
747 | |
748 |
749 |
750 | |
751 |
752 |
753 | linky custom attributes |
754 |
755 | <div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}"> </div>
756 | |
757 |
758 |
759 | |
760 |
761 |
762 | no filter |
763 | <div ng-bind="snippet"> </div> |
764 | |
765 |
766 |
767 |
768 |
769 | angular.module('linkyExample', ['ngSanitize'])
770 | .controller('ExampleController', ['$scope', function($scope) {
771 | $scope.snippet =
772 | 'Pretty text with some links:\n' +
773 | 'http://angularjs.org/,\n' +
774 | 'mailto:us@somewhere.org,\n' +
775 | 'another@somewhere.org,\n' +
776 | 'and one more: ftp://127.0.0.1/.';
777 | $scope.snippetWithSingleURL = 'http://angularjs.org/';
778 | }]);
779 |
780 |
781 | it('should linkify the snippet with urls', function() {
782 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
783 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
784 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
785 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
786 | });
787 |
788 | it('should not linkify snippet without the linky filter', function() {
789 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
790 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
791 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
792 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
793 | });
794 |
795 | it('should update', function() {
796 | element(by.model('snippet')).clear();
797 | element(by.model('snippet')).sendKeys('new http://link.');
798 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
799 | toBe('new http://link.');
800 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
801 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
802 | .toBe('new http://link.');
803 | });
804 |
805 | it('should work with the target property', function() {
806 | expect(element(by.id('linky-target')).
807 | element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()).
808 | toBe('http://angularjs.org/');
809 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
810 | });
811 |
812 | it('should optionally add custom attributes', function() {
813 | expect(element(by.id('linky-custom-attributes')).
814 | element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()).
815 | toBe('http://angularjs.org/');
816 | expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');
817 | });
818 |
819 |
820 | */
821 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
822 | var LINKY_URL_REGEXP =
823 | /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
824 | MAILTO_REGEXP = /^mailto:/i;
825 |
826 | var linkyMinErr = angular.$$minErr('linky');
827 | var isDefined = angular.isDefined;
828 | var isFunction = angular.isFunction;
829 | var isObject = angular.isObject;
830 | var isString = angular.isString;
831 |
832 | return function(text, target, attributes) {
833 | if (text == null || text === '') return text;
834 | if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
835 |
836 | var attributesFn =
837 | isFunction(attributes) ? attributes :
838 | isObject(attributes) ? function getAttributesObject() {return attributes;} :
839 | function getEmptyAttributesObject() {return {};};
840 |
841 | var match;
842 | var raw = text;
843 | var html = [];
844 | var url;
845 | var i;
846 | while ((match = raw.match(LINKY_URL_REGEXP))) {
847 | // We can not end in these as they are sometimes found at the end of the sentence
848 | url = match[0];
849 | // if we did not match ftp/http/www/mailto then assume mailto
850 | if (!match[2] && !match[4]) {
851 | url = (match[3] ? 'http://' : 'mailto:') + url;
852 | }
853 | i = match.index;
854 | addText(raw.substr(0, i));
855 | addLink(url, match[0].replace(MAILTO_REGEXP, ''));
856 | raw = raw.substring(i + match[0].length);
857 | }
858 | addText(raw);
859 | return $sanitize(html.join(''));
860 |
861 | function addText(text) {
862 | if (!text) {
863 | return;
864 | }
865 | html.push(sanitizeText(text));
866 | }
867 |
868 | function addLink(url, text) {
869 | var key, linkAttributes = attributesFn(url);
870 | html.push('
');
884 | addText(text);
885 | html.push('');
886 | }
887 | };
888 | }]);
889 |
890 |
891 | })(window, window.angular);
892 |
--------------------------------------------------------------------------------
/angular-sanitize.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.8.3
3 | (c) 2010-2020 Google LLC. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(s,e){'use strict';function O(e){var g=[];B(g,D).chars(e);return g.join("")}var C=e.$$minErr("$sanitize"),E,g,F,G,H,q,D,I,J,B;e.module("ngSanitize",[]).provider("$sanitize",function(){function h(a,d){return A(a.split(","),d)}function A(a,d){var c={},b;for(b=0;b
/g,">")}function z(a){for(;a;){if(a.nodeType===s.Node.ELEMENT_NODE)for(var d=a.attributes,c=0,b=d.length;c
"))},end:function(a){a=q(a);c||!0!==m[a]||!0===r[a]||(b(""),b(a),b(">"));a==c&&(c=!1)},chars:function(a){c||
11 | b(K(a))}}};I=s.Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)&16)};var Q=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,u=/([^#-~ |!])/g,r=h("area,br,col,hr,img,wbr"),x=h("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),p=h("rp,rt"),n=g({},p,x),x=g({},x,h("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul")),p=g({},p,h("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),
12 | l=h("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,stop,svg,switch,text,title,tspan"),w=h("script,style"),m=g({},r,x,p,n),N=h("background,cite,href,longdesc,src,xlink:href,xml:base"),n=h("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,valign,value,vspace,width"),
13 | p=h("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan",
14 | !0),L=g({},N,p,n),M=function(a,d){function c(b){b=""+b;try{var c=(new a.DOMParser).parseFromString(b,"text/html").body;c.firstChild.remove();return c}catch(d){}}var b;try{b=!!c("")}catch(f){b=!1}if(b)return c;if(!d||!d.implementation)throw C("noinert");b=d.implementation.createHTMLDocument("inert");var e=(b.documentElement||b.getDocumentElement()).querySelector("body");return function(a){e.innerHTML=a;d.documentMode&&z(e);return e}}(s,s.document)}).info({angularVersion:"1.8.3"});
15 | e.module("ngSanitize").filter("linky",["$sanitize",function(h){var g=/((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,t=/^mailto:/i,q=e.$$minErr("linky"),s=e.isDefined,z=e.isFunction,v=e.isObject,y=e.isString;return function(f,e,u){function r(e){e&&l.push(O(e))}function x(f,h){var g,a=p(f);l.push("');r(h);l.push("")}if(null==
16 | f||""===f)return f;if(!y(f))throw q("notstring",f);for(var p=z(u)?u:v(u)?function(){return u}:function(){return{}},n=f,l=[],w,m;f=n.match(g);)w=f[0],f[2]||f[4]||(w=(f[3]?"http://":"mailto:")+w),m=f.index,r(n.substr(0,m)),x(w,f[0].replace(t,"")),n=n.substring(m+f[0].length);r(n);return h(l.join(""))}}])})(window,window.angular);
17 | //# sourceMappingURL=angular-sanitize.min.js.map
18 |
--------------------------------------------------------------------------------
/angular-sanitize.min.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version":3,
3 | "file":"angular-sanitize.min.js",
4 | "lineCount":16,
5 | "mappings":"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",
6 | "sources":["angular-sanitize.js"],
7 | "names":["window","angular","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","$sanitizeMinErr","$$minErr","bind","extend","forEach","isArray","isDefined","lowercase","nodeContains","htmlParser","module","provider","$SanitizeProvider","stringToMap","str","lowercaseKeys","arrayToMap","split","items","obj","i","length","addElementsTo","elementsMap","newElements","attrToMap","attrs","map","ii","attr","name","value","encodeEntities","replace","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","stripCustomNsAttrs","node","nodeType","Node","ELEMENT_NODE","attributes","l","attrNode","attrName","toLowerCase","lastIndexOf","removeAttributeNode","nextNode","firstChild","getNonDescendant","propName","call","outerHTML","outerText","hasBeenInstantiated","svgEnabled","$get","$$sanitizeUri","validElements","svgElements","html","uri","isImage","test","enableSvg","this.enableSvg","addValidElements","this.addValidElements","elements","htmlElements","voidElements","htmlVoidElements","addValidAttrs","this.addValidAttrs","validAttrs","$$lowercase","htmlParserImpl","handler","undefined","inertBodyElement","getInertBodyElement","mXSSAttempts","innerHTML","start","nodeName","textContent","end","removeChild","htmlSanitizeWriterImpl","uriValidator","ignoreCurrentElement","out","push","tag","blockedElements","key","lkey","uriAttrs","prototype","contains","arg","compareDocumentPosition","optionalEndTagBlockElements","optionalEndTagInlineElements","optionalEndTagElements","blockElements","inlineElements","htmlAttrs","svgAttrs","document","getInertBodyElement_DOMParser","body","parseFromString","DOMParser","remove","e","implementation","inertDocument","createHTMLDocument","querySelector","documentElement","getDocumentElement","getInertBodyElement_InertDocument","documentMode","info","angularVersion","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","linkyMinErr","isFunction","isObject","isString","text","target","addText","addLink","url","linkAttributes","attributesFn","getAttributesObject","getEmptyAttributesObject","raw","match","index","substr","substring"]
8 | }
9 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-sanitize",
3 | "version": "1.8.3",
4 | "license": "MIT",
5 | "main": "./angular-sanitize.js",
6 | "ignore": [],
7 | "dependencies": {
8 | "angular": "1.8.3"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require('./angular-sanitize');
2 | module.exports = 'ngSanitize';
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-sanitize",
3 | "version": "1.8.3",
4 | "description": "AngularJS module for sanitizing HTML",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/angular/angular.js.git"
12 | },
13 | "keywords": [
14 | "angular",
15 | "framework",
16 | "browser",
17 | "html",
18 | "client-side"
19 | ],
20 | "author": "Angular Core Team ",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/angular/angular.js/issues"
24 | },
25 | "homepage": "http://angularjs.org",
26 | "jspm": {
27 | "shim": {
28 | "angular-sanitize": {
29 | "deps": ["angular"]
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------