Skip to content

Commit 2da8c58

Browse files
benelliottbenelliottgsa
authored andcommitted
Add preserveEscapedAttributes option to allow attributes on escaped disallowed tags to be retained
Fixes apostrophecms#540
1 parent f47281e commit 2da8c58

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

index.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,14 @@ function sanitizeHtml(html, options, _recursing) {
287287
}
288288
}
289289

290-
if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
290+
const isBeingEscaped = skip && (options.disallowedTagsMode === 'escape' || options.disallowedTagsMode === 'recursiveEscape');
291+
const shouldPreserveEscapedAttributes = isBeingEscaped && options.preserveEscapedAttributes;
292+
293+
if (shouldPreserveEscapedAttributes) {
294+
each(attribs, function(value, a) {
295+
result += ' ' + a + '="' + escapeHtml((value || ''), true) + '"';
296+
});
297+
} else if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
291298
each(attribs, function(value, a) {
292299
if (!VALID_HTML_ATTRIBUTE_NAME.test(a)) {
293300
// This prevents part of an attribute name in the output from being
@@ -893,7 +900,8 @@ sanitizeHtml.defaults = {
893900
allowedSchemesAppliedToAttributes: [ 'href', 'src', 'cite' ],
894901
allowProtocolRelative: true,
895902
enforceHtmlBoundary: false,
896-
parseStyleAttributes: true
903+
parseStyleAttributes: true,
904+
preserveEscapedAttributes: false
897905
};
898906

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

test/test.js

+22
Original file line numberDiff line numberDiff line change
@@ -1693,6 +1693,28 @@ describe('sanitizeHtml', function() {
16931693
disallowedTagsMode: 'completelyDiscard'
16941694
});
16951695

1696+
assert.equal(sanitizedHtml, expectedOutput);
1697+
});
1698+
it('should not preserve attributes on escaped disallowed tags when `preserveEscapedAttributes` is false', () => {
1699+
const inputHtml = '<div class="foo">Some Text</div>';
1700+
const expectedOutput = '&lt;div&gt;Some Text&lt;/div&gt;';
1701+
const sanitizedHtml = sanitizeHtml(inputHtml, {
1702+
allowedTags: [],
1703+
disallowedTagsMode: 'escape',
1704+
preserveEscapedAttributes: false
1705+
});
1706+
1707+
assert.equal(sanitizedHtml, expectedOutput);
1708+
});
1709+
it('should preserve attributes on escaped disallowed tags when `preserveEscapedAttributes` is true', () => {
1710+
const inputHtml = '<div class="foo">Some Text</div>';
1711+
const expectedOutput = '&lt;div class="foo"&gt;Some Text&lt;/div&gt;';
1712+
const sanitizedHtml = sanitizeHtml(inputHtml, {
1713+
allowedTags: [],
1714+
disallowedTagsMode: 'escape',
1715+
preserveEscapedAttributes: true
1716+
});
1717+
16961718
assert.equal(sanitizedHtml, expectedOutput);
16971719
});
16981720
});

0 commit comments

Comments
 (0)