Skip to content

Commit c52a9f0

Browse files
authored
Merge pull request #634 from zhna123/empty-alt
Added 'allowedEmptyAttributes' option and kept empty 'alt' value by default
2 parents cb6efe1 + 2c7ac45 commit c52a9f0

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## UNRELEASED
4+
5+
- Introduced the `allowedEmptyAttributes` option, enabling explicit specification of empty string values for select attributes, with the default attribute set to `alt`.
6+
37
## 2.11.0 (2023-06-21)
48

59
- Fix to allow `false` in `allowedClasses` attributes. Thanks to [Kevin Jiang](https://github.com/KevinSJ) for this fix!

index.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,11 @@ function sanitizeHtml(html, options, _recursing) {
295295
delete frame.attribs[a];
296296
return;
297297
}
298-
// If the value is empty, and this is a known non-boolean attribute, delete it
298+
// If the value is empty, check if the attribute is in the allowedEmptyAttributes array.
299+
// If it is not in the allowedEmptyAttributes array, and it is a known non-boolean attribute, delete it
299300
// List taken from https://html.spec.whatwg.org/multipage/indices.html#attributes-3
300-
if (value === '' && (options.nonBooleanAttributes.includes(a) || options.nonBooleanAttributes.includes('*'))) {
301+
if (value === '' && (!options.allowedEmptyAttributes.includes(a)) &&
302+
(options.nonBooleanAttributes.includes(a) || options.nonBooleanAttributes.includes('*'))) {
301303
delete frame.attribs[a];
302304
return;
303305
}
@@ -474,6 +476,8 @@ function sanitizeHtml(html, options, _recursing) {
474476
result += ' ' + a;
475477
if (value && value.length) {
476478
result += '="' + escapeHtml(value, true) + '"';
479+
} else if (options.allowedEmptyAttributes.includes(a)) {
480+
result += '=""';
477481
}
478482
} else {
479483
delete frame.attribs[a];
@@ -876,6 +880,9 @@ sanitizeHtml.defaults = {
876880
// these attributes would make sense if we did.
877881
img: [ 'src', 'srcset', 'alt', 'title', 'width', 'height', 'loading' ]
878882
},
883+
allowedEmptyAttributes: [
884+
'alt'
885+
],
879886
// Lots of these won't come up by default because we don't allow them
880887
selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
881888
// URL schemes we permit

test/test.js

+33
Original file line numberDiff line numberDiff line change
@@ -1616,4 +1616,37 @@ describe('sanitizeHtml', function() {
16161616
nonBooleanAttributes: [ '*' ]
16171617
}), '<input type="checkbox" />');
16181618
});
1619+
it('should not remove empty alt attribute value by default', function() {
1620+
assert.equal(sanitizeHtml('<img alt="" src="https://example.com/" />', {
1621+
allowedAttributes: { img: [ 'alt', 'src' ] },
1622+
allowedTags: [ 'img' ]
1623+
}), '<img alt="" src="https://example.com/" />');
1624+
});
1625+
it('should convert the implicit empty alt attribute value to be an empty string by default', function() {
1626+
assert.equal(sanitizeHtml('<img alt src="https://example.com/" />', {
1627+
allowedAttributes: { img: [ 'alt', 'src' ] },
1628+
allowedTags: [ 'img' ]
1629+
}), '<img alt="" src="https://example.com/" />');
1630+
});
1631+
it('should not remove empty alt attribute value by default when an empty nonBooleanAttributes option passed in', function() {
1632+
assert.equal(sanitizeHtml('<img alt="" src="https://example.com/" />', {
1633+
allowedAttributes: { img: [ 'alt', 'src' ] },
1634+
allowedTags: [ 'img' ],
1635+
nonBooleanAttributes: []
1636+
}), '<img alt="" src="https://example.com/" />');
1637+
});
1638+
it('should not remove the empty attributes specified in allowedEmptyAttributes option', function() {
1639+
assert.equal(sanitizeHtml('<img alt="" src="" />', {
1640+
allowedAttributes: { img: [ 'alt', 'src' ] },
1641+
allowedTags: [ 'img' ],
1642+
allowedEmptyAttributes: [ 'alt', 'src' ]
1643+
}), '<img alt="" src="" />');
1644+
});
1645+
it('should remove all the empty attributes when an empty allowedEmptyAttributes option passed in', function() {
1646+
assert.equal(sanitizeHtml('<img alt="" src="https://example.com/" target="" />', {
1647+
allowedAttributes: { img: [ 'alt', 'src' ] },
1648+
allowedTags: [ 'img' ],
1649+
allowedEmptyAttributes: []
1650+
}), '<img src="https://example.com/" />');
1651+
});
16191652
});

0 commit comments

Comments
 (0)