From 00e63aa23259398447215082d806cbc4d014809a Mon Sep 17 00:00:00 2001 From: btea <2356281422@qq.com> Date: Wed, 29 Nov 2023 21:58:00 +0800 Subject: [PATCH 1/3] #0@patch: Matches a partially invalid selector and throws an error. --- .../src/query-selector/QuerySelector.ts | 10 ++++++ .../test/query-selector/QuerySelector.test.ts | 32 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/packages/happy-dom/src/query-selector/QuerySelector.ts b/packages/happy-dom/src/query-selector/QuerySelector.ts index e0bd1f163..9798babe3 100644 --- a/packages/happy-dom/src/query-selector/QuerySelector.ts +++ b/packages/happy-dom/src/query-selector/QuerySelector.ts @@ -42,6 +42,11 @@ export default class QuerySelector { return new NodeList(); } + if (/^[.#\[]?\d/.test(selector)) { + throw new Error( + "Failed to execute 'querySelectorAll' on 'Element': '" + selector +"' is not a valid selector."); + } + const groups = SelectorParser.getSelectorGroups(selector); let matches: IDocumentPositionAndElement[] = []; @@ -89,6 +94,11 @@ export default class QuerySelector { return null; } + if (/^[.#\[]?\d/.test(selector)) { + throw new Error( + "Failed to execute 'querySelector' on 'Element': '" + selector +"' is not a valid selector."); + } + for (const items of SelectorParser.getSelectorGroups(selector)) { const match = node.nodeType === NodeTypeEnum.elementNode diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts index de5c15bbd..98a8e1bc2 100644 --- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts +++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts @@ -1126,5 +1126,37 @@ describe('QuerySelector', () => { expect(element === div.children[0]).toBe(true); expect(element2 === div.children[0]).toBe(true); }); + + it('querySelector Trhow an error when provide selector is a invalid value', () => { + const div = document.createElement('div'); + expect(() => div.querySelector('1')).toThrowError( + 'Failed to execute \'querySelector\' on \'Element\': \'1\' is not a valid selector.' + ); + expect(() => div.querySelector('[1')).toThrowError( + 'Failed to execute \'querySelector\' on \'Element\': \'[1\' is not a valid selector.' + ); + expect(() => div.querySelector('.1')).toThrowError( + 'Failed to execute \'querySelector\' on \'Element\': \'.1\' is not a valid selector.' + ); + expect(() => div.querySelector('#1')).toThrowError( + 'Failed to execute \'querySelector\' on \'Element\': \'#1\' is not a valid selector.' + ); + }); + + it('querySelectorAll Trhow an error when provide selector is a invalid value', () => { + const div = document.createElement('div'); + expect(() => div.querySelectorAll('1')).toThrowError( + 'Failed to execute \'querySelectorAll\' on \'Element\': \'1\' is not a valid selector.' + ); + expect(() => div.querySelectorAll('[1')).toThrowError( + 'Failed to execute \'querySelectorAll\' on \'Element\': \'[1\' is not a valid selector.' + ); + expect(() => div.querySelectorAll('.1')).toThrowError( + 'Failed to execute \'querySelectorAll\' on \'Element\': \'.1\' is not a valid selector.' + ); + expect(() => div.querySelectorAll('#1')).toThrowError( + 'Failed to execute \'querySelectorAll\' on \'Element\': \'#1\' is not a valid selector.' + ); + }); }); }); From cf5abd7e8a497ef284952c4d12aced6341d8071f Mon Sep 17 00:00:00 2001 From: btea <2356281422@qq.com> Date: Wed, 29 Nov 2023 22:05:56 +0800 Subject: [PATCH 2/3] #0@patch: Format code. --- .../src/query-selector/QuerySelector.ts | 10 ++++++++-- .../test/query-selector/QuerySelector.test.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/happy-dom/src/query-selector/QuerySelector.ts b/packages/happy-dom/src/query-selector/QuerySelector.ts index 9798babe3..f4160e9a9 100644 --- a/packages/happy-dom/src/query-selector/QuerySelector.ts +++ b/packages/happy-dom/src/query-selector/QuerySelector.ts @@ -44,7 +44,10 @@ export default class QuerySelector { if (/^[.#\[]?\d/.test(selector)) { throw new Error( - "Failed to execute 'querySelectorAll' on 'Element': '" + selector +"' is not a valid selector."); + "Failed to execute 'querySelectorAll' on 'Element': '" + + selector + + "' is not a valid selector." + ); } const groups = SelectorParser.getSelectorGroups(selector); @@ -96,7 +99,10 @@ export default class QuerySelector { if (/^[.#\[]?\d/.test(selector)) { throw new Error( - "Failed to execute 'querySelector' on 'Element': '" + selector +"' is not a valid selector."); + "Failed to execute 'querySelector' on 'Element': '" + + selector + + "' is not a valid selector." + ); } for (const items of SelectorParser.getSelectorGroups(selector)) { diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts index 98a8e1bc2..b21df10c0 100644 --- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts +++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts @@ -1130,32 +1130,32 @@ describe('QuerySelector', () => { it('querySelector Trhow an error when provide selector is a invalid value', () => { const div = document.createElement('div'); expect(() => div.querySelector('1')).toThrowError( - 'Failed to execute \'querySelector\' on \'Element\': \'1\' is not a valid selector.' + "Failed to execute 'querySelector' on 'Element': '1' is not a valid selector." ); expect(() => div.querySelector('[1')).toThrowError( - 'Failed to execute \'querySelector\' on \'Element\': \'[1\' is not a valid selector.' + "Failed to execute 'querySelector' on 'Element': '[1' is not a valid selector." ); expect(() => div.querySelector('.1')).toThrowError( - 'Failed to execute \'querySelector\' on \'Element\': \'.1\' is not a valid selector.' + "Failed to execute 'querySelector' on 'Element': '.1' is not a valid selector." ); expect(() => div.querySelector('#1')).toThrowError( - 'Failed to execute \'querySelector\' on \'Element\': \'#1\' is not a valid selector.' + "Failed to execute 'querySelector' on 'Element': '#1' is not a valid selector." ); }); it('querySelectorAll Trhow an error when provide selector is a invalid value', () => { const div = document.createElement('div'); expect(() => div.querySelectorAll('1')).toThrowError( - 'Failed to execute \'querySelectorAll\' on \'Element\': \'1\' is not a valid selector.' + "Failed to execute 'querySelectorAll' on 'Element': '1' is not a valid selector." ); expect(() => div.querySelectorAll('[1')).toThrowError( - 'Failed to execute \'querySelectorAll\' on \'Element\': \'[1\' is not a valid selector.' + "Failed to execute 'querySelectorAll' on 'Element': '[1' is not a valid selector." ); expect(() => div.querySelectorAll('.1')).toThrowError( - 'Failed to execute \'querySelectorAll\' on \'Element\': \'.1\' is not a valid selector.' + "Failed to execute 'querySelectorAll' on 'Element': '.1' is not a valid selector." ); expect(() => div.querySelectorAll('#1')).toThrowError( - 'Failed to execute \'querySelectorAll\' on \'Element\': \'#1\' is not a valid selector.' + "Failed to execute 'querySelectorAll' on 'Element': '#1' is not a valid selector." ); }); }); From 61b3137eade246c8e7b76426174266f943e3306f Mon Sep 17 00:00:00 2001 From: David Date: Mon, 15 Jan 2024 01:27:47 +0100 Subject: [PATCH 3/3] #1170@patch: Throws an error when providing an invalid selector to querySelector() and querySelectorAll(). --- .../src/query-selector/QuerySelector.ts | 33 ++++++++++----- .../test/query-selector/QuerySelector.test.ts | 42 +++++++++---------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/packages/happy-dom/src/query-selector/QuerySelector.ts b/packages/happy-dom/src/query-selector/QuerySelector.ts index e6fb311ec..3a7b60c80 100644 --- a/packages/happy-dom/src/query-selector/QuerySelector.ts +++ b/packages/happy-dom/src/query-selector/QuerySelector.ts @@ -16,6 +16,11 @@ type IDocumentPositionAndElement = { element: IElement; }; +/** + * Invalid Selector RegExp. + */ +const INVALID_SELECTOR_REGEXP = /^[.#\[]?\d/; + /** * Utility for query selection in an HTML element. * @@ -35,7 +40,7 @@ export default class QuerySelector { ): INodeList { if (selector === '') { throw new Error( - "Failed to execute 'querySelectorAll' on 'Element': The provided selector is empty." + `Failed to execute 'querySelectorAll' on '${node.constructor.name}': The provided selector is empty.` ); } @@ -43,11 +48,9 @@ export default class QuerySelector { return new NodeList(); } - if (/^[.#\[]?\d/.test(selector)) { + if (INVALID_SELECTOR_REGEXP.test(selector)) { throw new Error( - "Failed to execute 'querySelectorAll' on 'Element': '" + - selector + - "' is not a valid selector." + `Failed to execute 'querySelectorAll' on '${node.constructor.name}': '${selector}' is not a valid selector.` ); } @@ -87,10 +90,10 @@ export default class QuerySelector { public static querySelector( node: IElement | IDocument | IDocumentFragment, selector: string - ): IElement { + ): IElement | null { if (selector === '') { throw new Error( - "Failed to execute 'querySelector' on 'Element': The provided selector is empty." + `Failed to execute 'querySelector' on '${node.constructor.name}': The provided selector is empty.` ); } @@ -98,11 +101,9 @@ export default class QuerySelector { return null; } - if (/^[.#\[]?\d/.test(selector)) { + if (INVALID_SELECTOR_REGEXP.test(selector)) { throw new Error( - "Failed to execute 'querySelector' on 'Element': '" + - selector + - "' is not a valid selector." + `Failed to execute 'querySelector' on '${node.constructor.name}': '${selector}' is not a valid selector.` ); } @@ -128,12 +129,22 @@ export default class QuerySelector { * @returns Result. */ public static match(element: IElement, selector: string): ISelectorMatch | null { + if (!selector) { + return null; + } + if (selector === '*') { return { priorityWeight: 1 }; } + if (INVALID_SELECTOR_REGEXP.test(selector)) { + throw new Error( + `Failed to execute 'match' on '${element.constructor.name}': '${selector}' is not a valid selector.` + ); + } + for (const items of SelectorParser.getSelectorGroups(selector)) { const result = this.matchSelector(element, element, items.reverse()); diff --git a/packages/happy-dom/test/query-selector/QuerySelector.test.ts b/packages/happy-dom/test/query-selector/QuerySelector.test.ts index b21df10c0..caa3d1445 100644 --- a/packages/happy-dom/test/query-selector/QuerySelector.test.ts +++ b/packages/happy-dom/test/query-selector/QuerySelector.test.ts @@ -975,6 +975,22 @@ describe('QuerySelector', () => { expect(elements.length).toBe(0); }); + + it('Throws an error when providing an invalid selector', () => { + const div = document.createElement('div'); + expect(() => div.querySelectorAll('1')).toThrowError( + "Failed to execute 'querySelectorAll' on 'HTMLElement': '1' is not a valid selector." + ); + expect(() => div.querySelectorAll('[1')).toThrowError( + "Failed to execute 'querySelectorAll' on 'HTMLElement': '[1' is not a valid selector." + ); + expect(() => div.querySelectorAll('.1')).toThrowError( + "Failed to execute 'querySelectorAll' on 'HTMLElement': '.1' is not a valid selector." + ); + expect(() => div.querySelectorAll('#1')).toThrowError( + "Failed to execute 'querySelectorAll' on 'HTMLElement': '#1' is not a valid selector." + ); + }); }); describe('querySelector', () => { @@ -1127,35 +1143,19 @@ describe('QuerySelector', () => { expect(element2 === div.children[0]).toBe(true); }); - it('querySelector Trhow an error when provide selector is a invalid value', () => { + it('Throws an error when providing an invalid selector', () => { const div = document.createElement('div'); expect(() => div.querySelector('1')).toThrowError( - "Failed to execute 'querySelector' on 'Element': '1' is not a valid selector." + "Failed to execute 'querySelector' on 'HTMLElement': '1' is not a valid selector." ); expect(() => div.querySelector('[1')).toThrowError( - "Failed to execute 'querySelector' on 'Element': '[1' is not a valid selector." + "Failed to execute 'querySelector' on 'HTMLElement': '[1' is not a valid selector." ); expect(() => div.querySelector('.1')).toThrowError( - "Failed to execute 'querySelector' on 'Element': '.1' is not a valid selector." + "Failed to execute 'querySelector' on 'HTMLElement': '.1' is not a valid selector." ); expect(() => div.querySelector('#1')).toThrowError( - "Failed to execute 'querySelector' on 'Element': '#1' is not a valid selector." - ); - }); - - it('querySelectorAll Trhow an error when provide selector is a invalid value', () => { - const div = document.createElement('div'); - expect(() => div.querySelectorAll('1')).toThrowError( - "Failed to execute 'querySelectorAll' on 'Element': '1' is not a valid selector." - ); - expect(() => div.querySelectorAll('[1')).toThrowError( - "Failed to execute 'querySelectorAll' on 'Element': '[1' is not a valid selector." - ); - expect(() => div.querySelectorAll('.1')).toThrowError( - "Failed to execute 'querySelectorAll' on 'Element': '.1' is not a valid selector." - ); - expect(() => div.querySelectorAll('#1')).toThrowError( - "Failed to execute 'querySelectorAll' on 'Element': '#1' is not a valid selector." + "Failed to execute 'querySelector' on 'HTMLElement': '#1' is not a valid selector." ); }); });