sanitize-html 2.15.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +54 -1
  2. package/index.js +17 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -745,7 +745,7 @@ This will transform `<disallowed>content <allowed>content</allowed> </disallowed
745
745
 
746
746
  #### Escape the disallowed tag and all its children even for allowed tags.
747
747
 
748
- if you set `disallowedTagsMode` to `recursiveEscape`, disallowed tag and its children will be escaped even for allowed tags
748
+ if you set `disallowedTagsMode` to `recursiveEscape`, disallowed tags and their children will be escaped even for allowed tags:
749
749
 
750
750
  ```js
751
751
  disallowedTagsMode: `recursiveEscape`
@@ -753,6 +753,15 @@ disallowedTagsMode: `recursiveEscape`
753
753
 
754
754
  This will transform `<disallowed>hello<p>world</p></disallowed>` to `&lt;disallowed&gt;hello&lt;p&gt;world&lt;/p&gt;&lt;/disallowed&gt;`
755
755
 
756
+ #### Escape the disallowed tag, including all its attributes.
757
+
758
+ By default, attributes are not preserved when tags are escaped. You can set `preserveEscapedAttributes` to `true` to
759
+ keep the attributes, which will also be escaped and therefore have no effect on the browser.
760
+
761
+ ```js
762
+ preserveEscapedAttributes: true
763
+ ```
764
+
756
765
  ### Ignore style attribute contents
757
766
 
758
767
  Instead of discarding faulty style attributes, you can allow them by disabling the parsing of style attributes:
@@ -781,6 +790,50 @@ nestingLimit: 6
781
790
 
782
791
  This will prevent the user from nesting tags more than 6 levels deep. Tags deeper than that are stripped out exactly as if they were disallowed. Note that this means text is preserved in the usual ways where appropriate.
783
792
 
793
+ ### Advanced filtering
794
+
795
+ For more advanced filtering you can hook directly into the parsing process using tag open and tag close events.
796
+
797
+ The `onOpenTag` event is triggered when an opening tag is encountered. It has two arguments:
798
+ - `tagName`: The name of the tag.
799
+ - `attribs`: An object containing the tag's attributes, e.g. `{ src: "/path/to/tux.png" }`.
800
+
801
+ The `onCloseTag` event is triggered when a closing tag is encountered. It has the following arguments:
802
+ - `tagName`: The name of the tag.
803
+ - `isImplied`: A boolean indicating whether the closing tag is implied (e.g. `<p>foo<p>bar`) or explicit (e.g. `<p>foo</p><p>bar</p>`).
804
+
805
+ For example, you may want to add spaces around a removed tag, like this:
806
+ ```js
807
+ const allowedTags = [ 'b' ];
808
+ let addSpace = false;
809
+ const sanitizedHtml = sanitizeHtml(
810
+ 'There should be<div><p>spaces</p></div>between <b>these</b> words.',
811
+ {
812
+ allowedTags,
813
+ onOpenTag: (tagName, attribs) => {
814
+ addSpace = !allowedTags.includes(tagName);
815
+ },
816
+ onCloseTag: (tagName, isImplied) => {
817
+ addSpace = !allowedTags.includes(tagName);
818
+ },
819
+ textFilter: (text) => {
820
+ if (addSpace) {
821
+ addSpace = false;
822
+ return ' ' + text;
823
+ }
824
+ return text;
825
+ }
826
+ }
827
+ );
828
+ ```
829
+
830
+ In this example, we are setting a flag when a tag that will be removed has been opened or closed. Then we use the `textFilter` to modify the text to include spaces. The example should produce:
831
+ ```
832
+ There should be spaces between <b>these</b> words.
833
+ ```
834
+
835
+ This is a simplified example that is not meant to be production-ready. For your specific case, you may want to keep track of currently open tags, using the open and close events to push and pop items on the stack, or only insert spaces next to a subset of disallowed tags.
836
+
784
837
  ## About ApostropheCMS
785
838
 
786
839
  sanitize-html was created at [P'unk Avenue](https://punkave.com) for use in [ApostropheCMS](https://apostrophecms.com), an open-source content management system built on Node.js. If you like sanitize-html you should definitely check out ApostropheCMS.
package/index.js CHANGED
@@ -220,6 +220,10 @@ function sanitizeHtml(html, options, _recursing) {
220
220
 
221
221
  const parser = new htmlparser.Parser({
222
222
  onopentag: function(name, attribs) {
223
+ if (options.onOpenTag) {
224
+ options.onOpenTag(name, attribs);
225
+ }
226
+
223
227
  // If `enforceHtmlBoundary` is `true` and this has found the opening
224
228
  // `html` tag, reset the state.
225
229
  if (options.enforceHtmlBoundary && name === 'html') {
@@ -296,7 +300,14 @@ function sanitizeHtml(html, options, _recursing) {
296
300
  }
297
301
  }
298
302
 
299
- if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
303
+ const isBeingEscaped = skip && (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape');
304
+ const shouldPreserveEscapedAttributes = isBeingEscaped && options.preserveEscapedAttributes;
305
+
306
+ if (shouldPreserveEscapedAttributes) {
307
+ each(attribs, function(value, a) {
308
+ result += ' ' + a + '="' + escapeHtml((value || ''), true) + '"';
309
+ });
310
+ } else if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
300
311
  each(attribs, function(value, a) {
301
312
  if (!VALID_HTML_ATTRIBUTE_NAME.test(a)) {
302
313
  // This prevents part of an attribute name in the output from being
@@ -544,6 +555,9 @@ function sanitizeHtml(html, options, _recursing) {
544
555
  }
545
556
  },
546
557
  onclosetag: function(name, isImplied) {
558
+ if (options.onCloseTag) {
559
+ options.onCloseTag(name, isImplied);
560
+ }
547
561
 
548
562
  if (skipText) {
549
563
  skipTextDepth--;
@@ -916,7 +930,8 @@ sanitizeHtml.defaults = {
916
930
  allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
917
931
  allowProtocolRelative: true,
918
932
  enforceHtmlBoundary: false,
919
- parseStyleAttributes: true
933
+ parseStyleAttributes: true,
934
+ preserveEscapedAttributes: false
920
935
  };
921
936
 
922
937
  sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanitize-html",
3
- "version": "2.15.0",
3
+ "version": "2.17.0",
4
4
  "description": "Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis",
5
5
  "sideEffects": false,
6
6
  "main": "index.js",