Skip to content

Commit ae1dc35

Browse files
benelliottbenelliottgsa
authored andcommitted
Add preserveEscapedAttributes option to allow attributes on escaped disallowed tags to be retained
Fixes #540
1 parent 3b45c7c commit ae1dc35

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

index.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,14 @@ function sanitizeHtml(html, options, _recursing) {
300300
}
301301
}
302302

303-
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['*']) {
304311
each(attribs, function(value, a) {
305312
if (!VALID_HTML_ATTRIBUTE_NAME.test(a)) {
306313
// This prevents part of an attribute name in the output from being
@@ -923,7 +930,8 @@ sanitizeHtml.defaults = {
923930
allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
924931
allowProtocolRelative: true,
925932
enforceHtmlBoundary: false,
926-
parseStyleAttributes: true
933+
parseStyleAttributes: true,
934+
preserveEscapedAttributes: false
927935
};
928936

929937
sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {

test/test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,4 +1811,26 @@ describe('sanitizeHtml', function() {
18111811
);
18121812
assert.equal(sanitizedHtml, expectedOutput);
18131813
});
1814+
it('should not preserve attributes on escaped disallowed tags when `preserveEscapedAttributes` is false', () => {
1815+
const inputHtml = '<div class="foo">Some Text</div>';
1816+
const expectedOutput = '&lt;div&gt;Some Text&lt;/div&gt;';
1817+
const sanitizedHtml = sanitizeHtml(inputHtml, {
1818+
allowedTags: [],
1819+
disallowedTagsMode: 'escape',
1820+
preserveEscapedAttributes: false
1821+
});
1822+
1823+
assert.equal(sanitizedHtml, expectedOutput);
1824+
});
1825+
it('should preserve attributes on escaped disallowed tags when `preserveEscapedAttributes` is true', () => {
1826+
const inputHtml = '<div class="foo">Some Text</div>';
1827+
const expectedOutput = '&lt;div class="foo"&gt;Some Text&lt;/div&gt;';
1828+
const sanitizedHtml = sanitizeHtml(inputHtml, {
1829+
allowedTags: [],
1830+
disallowedTagsMode: 'escape',
1831+
preserveEscapedAttributes: true
1832+
});
1833+
1834+
assert.equal(sanitizedHtml, expectedOutput);
1835+
});
18141836
});

0 commit comments

Comments
 (0)