aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Vick <[email protected]>2021-02-03 20:58:54 +0100
committerGitHub <[email protected]>2021-02-03 21:58:54 +0200
commit2a9d72133d52af1ca72944f1d19474957b54d618 (patch)
treebc6fd0cb03ebe23636fc4ef08ce5b9b37a797a96
parent3770b7b9e3fd92b164a58caef05a4d9cd650a86a (diff)
downloadbootstrap-2a9d72133d52af1ca72944f1d19474957b54d618.tar.xz
bootstrap-2a9d72133d52af1ca72944f1d19474957b54d618.zip
Prevent `getSelector` from returning URLs as selector (#32586)
* added checks to getSelector in util to prevent returning hrefs that are invalid selectors * restored compatibility for the class selector and added test cases for keeping urls from being returned as a selector Co-authored-by: XhmikosR <[email protected]>
-rw-r--r--js/src/util/index.js15
-rw-r--r--js/tests/unit/util/index.spec.js22
2 files changed, 36 insertions, 1 deletions
diff --git a/js/src/util/index.js b/js/src/util/index.js
index 22d0a578b..bd519cce0 100644
--- a/js/src/util/index.js
+++ b/js/src/util/index.js
@@ -36,7 +36,20 @@ const getSelector = element => {
let selector = element.getAttribute('data-bs-target')
if (!selector || selector === '#') {
- const hrefAttr = element.getAttribute('href')
+ let hrefAttr = element.getAttribute('href')
+
+ // The only valid content that could double as a selector are IDs or classes,
+ // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
+ // `document.querySelector` will rightfully complain it is invalid.
+ // See https://github.com/twbs/bootstrap/issues/32273
+ if (!hrefAttr || (!hrefAttr.includes('#') && !hrefAttr.startsWith('.'))) {
+ return null
+ }
+
+ // Just in case some CMS puts out a full URL with the anchor appended
+ if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
+ hrefAttr = '#' + hrefAttr.split('#')[1]
+ }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
}
diff --git a/js/tests/unit/util/index.spec.js b/js/tests/unit/util/index.spec.js
index 00ab44f1e..935e021dd 100644
--- a/js/tests/unit/util/index.spec.js
+++ b/js/tests/unit/util/index.spec.js
@@ -57,6 +57,28 @@ describe('Util', () => {
expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
})
+ it('should return null if a selector from a href is a url without an anchor', () => {
+ fixtureEl.innerHTML = [
+ '<a id="test" data-bs-target="#" href="foo/bar.html"></a>',
+ '<div class="target"></div>'
+ ].join('')
+
+ const testEl = fixtureEl.querySelector('#test')
+
+ expect(Util.getSelectorFromElement(testEl)).toBeNull()
+ })
+
+ it('should return the anchor if a selector from a href is a url', () => {
+ fixtureEl.innerHTML = [
+ '<a id="test" data-bs-target="#" href="foo/bar.html#target"></a>',
+ '<div id="target"></div>'
+ ].join('')
+
+ const testEl = fixtureEl.querySelector('#test')
+
+ expect(Util.getSelectorFromElement(testEl)).toEqual('#target')
+ })
+
it('should return null if selector not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'