diff --git a/javascript/externs/web/webstorage.js b/javascript/externs/web/webstorage.js index eee69d258145..7a41cccdd430 100644 --- a/javascript/externs/web/webstorage.js +++ b/javascript/externs/web/webstorage.js @@ -97,16 +97,40 @@ WindowLocalStorage.prototype.localStorage; */ Window.prototype.localStorage; +/** + * @record + * @extends {EventInit} + * @see https://html.spec.whatwg.org/multipage/webstorage.html#dictdef-storageeventinit + */ +function StorageEventInit() {} + +/** @type {(?string|undefined)} */ +StorageEventInit.prototype.key; + +/** @type {(?string|undefined)} */ +StorageEventInit.prototype.oldValue; + +/** @type {(?string|undefined)} */ +StorageEventInit.prototype.newValue; + +/** @type {(string|undefined)} */ +StorageEventInit.prototype.url; + +/** @type {(?Storage|undefined)} */ +StorageEventInit.prototype.storageArea; + /** * This is the storage event interface. - * @see http://www.w3.org/TR/2011/CR-webstorage-20111208/#the-storage-event + * @see https://html.spec.whatwg.org/multipage/webstorage.html#the-storageevent-interface * @extends {Event} * @constructor + * @param {string} type + * @param {StorageEventInit=} opt_eventInitDict */ -function StorageEvent() {} +function StorageEvent(type, opt_eventInitDict) {} /** - * @type {string} + * @type {?string} */ StorageEvent.prototype.key; @@ -132,17 +156,16 @@ StorageEvent.prototype.storageArea; /** * @param {string} typeArg - * @param {boolean} canBubbleArg - * @param {boolean} cancelableArg - * @param {string} keyArg - * @param {?string} oldValueArg - * @param {?string} newValueArg - * @param {string} urlArg - * @param {?Storage} storageAreaArg + * @param {boolean=} canBubbleArg + * @param {boolean=} cancelableArg + * @param {?string=} keyArg + * @param {?string=} oldValueArg + * @param {?string=} newValueArg + * @param {string=} urlArg + * @param {?Storage=} storageAreaArg * @return {void} */ StorageEvent.prototype.initStorageEvent = function(typeArg, canBubbleArg, cancelableArg, keyArg, oldValueArg, newValueArg, urlArg, storageAreaArg) {}; - diff --git a/javascript/ql/src/change-notes/2026-10-21-storageevent-constructor-arity.md b/javascript/ql/src/change-notes/2026-10-21-storageevent-constructor-arity.md new file mode 100644 index 000000000000..4ebe50525e99 --- /dev/null +++ b/javascript/ql/src/change-notes/2026-10-21-storageevent-constructor-arity.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Valid arguments passed to the `StorageEvent` constructor no longer produce alerts from `js/superfluous-trailing-arguments`. \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/SpuriousArguments.expected b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/SpuriousArguments.expected index 40493b31b1ec..2ee2f0a55f4e 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/SpuriousArguments.expected +++ b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/SpuriousArguments.expected @@ -7,6 +7,7 @@ | reflection.js:6:15:6:15 | 1 | Superfluous argument passed to $@. | reflection.js:1:1:1:23 | functio ... eturn;} | function f0 | | reflection.js:7:15:7:18 | 1 | Superfluous arguments passed to $@. | reflection.js:1:1:1:23 | functio ... eturn;} | function f0 | | reflection.js:12:18:12:18 | 2 | Superfluous argument passed to $@. | reflection.js:2:1:2:24 | functio ... eturn;} | function f1 | +| storageEvent.js:14:33:14:39 | "extra" | Superfluous argument passed to $@. | externs.js:55:1:55:49 | functio ... ict) {} | function StorageEvent | | thisparameter.ts:4:11:4:12 | 45 | Superfluous argument passed to $@. | thisparameter.ts:1:1:1:45 | functio ... eturn;} | function foo | | transformstream.ts:15:33:15:34 | {} | Superfluous argument passed to $@. | externs.js:48:1:48:76 | functio ... egy) {} | function TransformStream | | tst.js:10:3:10:5 | g() | Superfluous argument passed to $@. | tst.js:1:1:4:1 | functio ... x+19;\\n} | function f | diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js index cc3bf09cc149..f4a58aeb59bf 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js @@ -47,4 +47,11 @@ Number.parseFloat = function(num) {}; */ function TransformStream(transformer, writableStrategy, readableStrategy) {} +/** + * @constructor + * @param {string} type + * @param {StorageEventInit=} opt_eventInitDict + */ +function StorageEvent(type, opt_eventInitDict) {} + /** @externs */ diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/storageEvent.js b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/storageEvent.js new file mode 100644 index 000000000000..43b709ca861a --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/storageEvent.js @@ -0,0 +1,14 @@ +new StorageEvent("storage"); +new StorageEvent("storage", {}); +new StorageEvent("storage", { key: "k", newValue: "v" }); +new StorageEvent("storage", { + key: null, + oldValue: null, + newValue: null, + url: "", + storageArea: null, + bubbles: false, + cancelable: false, + composed: false +}); +new StorageEvent("storage", {}, "extra"); // $ Alert