mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-11 16:14:04 +02:00
throw error when folks try to use a bad selector
This commit is contained in:
@@ -79,14 +79,11 @@ const Util = (($) => {
|
|||||||
let selector = element.getAttribute('data-target')
|
let selector = element.getAttribute('data-target')
|
||||||
|
|
||||||
if (!selector || selector === '#') {
|
if (!selector || selector === '#') {
|
||||||
selector = (element.getAttribute('href') || '').trim()
|
const hrefAttr = element.getAttribute('href')
|
||||||
|
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return selector && document.querySelector(selector) ? selector : null
|
||||||
return document.querySelector(selector) ? selector : null
|
|
||||||
} catch (err) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getTransitionDurationFromElement(element) {
|
getTransitionDurationFromElement(element) {
|
||||||
|
@@ -216,30 +216,6 @@ $(function () {
|
|||||||
$dropdown.trigger('click')
|
$dropdown.trigger('click')
|
||||||
})
|
})
|
||||||
|
|
||||||
QUnit.test('should test if element has a # before assuming it\'s a selector', function (assert) {
|
|
||||||
assert.expect(1)
|
|
||||||
var done = assert.async()
|
|
||||||
var dropdownHTML = '<div class="tabs">' +
|
|
||||||
'<div class="dropdown">' +
|
|
||||||
'<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
|
|
||||||
'<div class="dropdown-menu">' +
|
|
||||||
'<a class="dropdown-item" href="#">Secondary link</a>' +
|
|
||||||
'<a class="dropdown-item" href="#">Something else here</a>' +
|
|
||||||
'<div class="divider"/>' +
|
|
||||||
'<a class="dropdown-item" href="#">Another link</a>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>'
|
|
||||||
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
|
|
||||||
$dropdown
|
|
||||||
.parent('.dropdown')
|
|
||||||
.on('shown.bs.dropdown', function () {
|
|
||||||
assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
$dropdown.trigger('click')
|
|
||||||
})
|
|
||||||
|
|
||||||
QUnit.test('should remove "show" class if body is clicked', function (assert) {
|
QUnit.test('should remove "show" class if body is clicked', function (assert) {
|
||||||
assert.expect(2)
|
assert.expect(2)
|
||||||
var done = assert.async()
|
var done = assert.async()
|
||||||
|
@@ -607,36 +607,40 @@ $(function () {
|
|||||||
assert.expect(1)
|
assert.expect(1)
|
||||||
var done = assert.async()
|
var done = assert.async()
|
||||||
|
|
||||||
var $toggleBtn = $('<button data-toggle="modal" data-target="<div id="modal-test"><div class="contents"<div<div id="close" data-dismiss="modal"/></div></div>"/>')
|
try {
|
||||||
.appendTo('#qunit-fixture')
|
var $toggleBtn = $('<button data-toggle="modal" data-target="<div id="modal-test"><div class="contents"<div<div id="close" data-dismiss="modal"/></div></div>"/>')
|
||||||
|
.appendTo('#qunit-fixture')
|
||||||
|
|
||||||
$toggleBtn.trigger('click')
|
$toggleBtn.trigger('click')
|
||||||
setTimeout(function () {
|
} catch (e) {
|
||||||
assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
|
assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
|
||||||
done()
|
done()
|
||||||
}, 1)
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
QUnit.test('should not execute js from target', function (assert) {
|
QUnit.test('should not execute js from target', function (assert) {
|
||||||
assert.expect(0)
|
assert.expect(0)
|
||||||
var done = assert.async()
|
var done = assert.async()
|
||||||
|
|
||||||
// This toggle button contains XSS payload in its data-target
|
try {
|
||||||
// Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
|
// This toggle button contains XSS payload in its data-target
|
||||||
// a script element works in manual tests though, so here it is likely blocked by the qunit framework
|
// Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
|
||||||
var $toggleBtn = $('<button data-toggle="modal" data-target="<div><image src="missing.png" onerror="$('#qunit-fixture button.control').trigger('click')"></div>"/>')
|
// a script element works in manual tests though, so here it is likely blocked by the qunit framework
|
||||||
.appendTo('#qunit-fixture')
|
var $toggleBtn = $('<button data-toggle="modal" data-target="<div><image src="missing.png" onerror="$('#qunit-fixture button.control').trigger('click')"></div>"/>')
|
||||||
// The XSS payload above does not have a closure over this function and cannot access the assert object directly
|
.appendTo('#qunit-fixture')
|
||||||
// However, it can send a click event to the following control button, which will then fail the assert
|
// The XSS payload above does not have a closure over this function and cannot access the assert object directly
|
||||||
$('<button>')
|
// However, it can send a click event to the following control button, which will then fail the assert
|
||||||
.addClass('control')
|
$('<button>')
|
||||||
.on('click', function () {
|
.addClass('control')
|
||||||
assert.notOk(true, 'XSS payload is not executed as js')
|
.on('click', function () {
|
||||||
})
|
assert.notOk(true, 'XSS payload is not executed as js')
|
||||||
.appendTo('#qunit-fixture')
|
})
|
||||||
|
.appendTo('#qunit-fixture')
|
||||||
|
|
||||||
$toggleBtn.trigger('click')
|
$toggleBtn.trigger('click')
|
||||||
setTimeout(done, 500)
|
} catch (e) {
|
||||||
|
done()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
QUnit.test('should not try to open a modal which is already visible', function (assert) {
|
QUnit.test('should not try to open a modal which is already visible', function (assert) {
|
||||||
|
@@ -186,8 +186,8 @@ $(function () {
|
|||||||
'<ul class="drop nav">' +
|
'<ul class="drop nav">' +
|
||||||
' <li class="dropdown"><a data-toggle="dropdown" href="#">1</a>' +
|
' <li class="dropdown"><a data-toggle="dropdown" href="#">1</a>' +
|
||||||
' <ul class="dropdown-menu nav">' +
|
' <ul class="dropdown-menu nav">' +
|
||||||
' <li><a href="#1-1" data-toggle="tab">1-1</a></li>' +
|
' <li><a href="#a1-1" data-toggle="tab">1-1</a></li>' +
|
||||||
' <li><a href="#1-2" data-toggle="tab">1-2</a></li>' +
|
' <li><a href="#a1-2" data-toggle="tab">1-2</a></li>' +
|
||||||
' </ul>' +
|
' </ul>' +
|
||||||
' </li>' +
|
' </li>' +
|
||||||
'</ul>'
|
'</ul>'
|
||||||
@@ -198,10 +198,10 @@ $(function () {
|
|||||||
.end()
|
.end()
|
||||||
.find('ul > li:last-child a')
|
.find('ul > li:last-child a')
|
||||||
.on('show.bs.tab', function (e) {
|
.on('show.bs.tab', function (e) {
|
||||||
assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
|
assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
|
||||||
})
|
})
|
||||||
.on('shown.bs.tab', function (e) {
|
.on('shown.bs.tab', function (e) {
|
||||||
assert.strictEqual(e.relatedTarget.hash, '#1-1', 'references correct element as relatedTarget')
|
assert.strictEqual(e.relatedTarget.hash, '#a1-1', 'references correct element as relatedTarget')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
.bootstrapTab('show')
|
.bootstrapTab('show')
|
||||||
|
@@ -20,6 +20,19 @@ $(function () {
|
|||||||
assert.strictEqual(Util.getSelectorFromElement($el2[0]), null)
|
assert.strictEqual(Util.getSelectorFromElement($el2[0]), null)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
QUnit.test('Util.getSelectorFromElement should throw error when there is a bad selector', function (assert) {
|
||||||
|
assert.expect(2)
|
||||||
|
|
||||||
|
var $el = $('<div data-target="#1"></div>').appendTo($('#qunit-fixture'))
|
||||||
|
|
||||||
|
try {
|
||||||
|
assert.ok(true, 'trying to use a bad selector')
|
||||||
|
Util.getSelectorFromElement($el[0])
|
||||||
|
} catch (e) {
|
||||||
|
assert.ok(e instanceof DOMException)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
QUnit.test('Util.typeCheckConfig should thrown an error when a bad config is passed', function (assert) {
|
QUnit.test('Util.typeCheckConfig should thrown an error when a bad config is passed', function (assert) {
|
||||||
assert.expect(1)
|
assert.expect(1)
|
||||||
var namePlugin = 'collapse'
|
var namePlugin = 'collapse'
|
||||||
|
Reference in New Issue
Block a user