diff --git a/src/webui/www/eslint.config.mjs b/src/webui/www/eslint.config.mjs index ed1d8c7f8..650e18069 100644 --- a/src/webui/www/eslint.config.mjs +++ b/src/webui/www/eslint.config.mjs @@ -27,6 +27,7 @@ export default [ }, rules: { "eqeqeq": "error", + "guard-for-in": "error", "no-undef": "off", "no-unused-vars": "off", "no-var": "error", diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index db9d7595f..0e0384071 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -825,6 +825,9 @@ window.addEventListener("DOMContentLoaded", () => { if (response["torrents"]) { let updateTorrentList = false; for (const key in response["torrents"]) { + if (!Object.hasOwn(response["torrents"], key)) + continue; + response["torrents"][key]["hash"] = key; response["torrents"][key]["rowId"] = key; if (response["torrents"][key]["state"]) @@ -853,8 +856,11 @@ window.addEventListener("DOMContentLoaded", () => { torrentsTable.altRow(); if (response["server_state"]) { const tmp = response["server_state"]; - for (const k in tmp) + for (const k in tmp) { + if (!Object.hasOwn(tmp, k)) + continue; serverState[k] = tmp[k]; + } processServerState(); } updateFiltersList(); diff --git a/src/webui/www/private/scripts/download.js b/src/webui/www/private/scripts/download.js index c0ec1b492..ce1df5c70 100644 --- a/src/webui/www/private/scripts/download.js +++ b/src/webui/www/private/scripts/download.js @@ -47,6 +47,9 @@ window.qBittorrent.Download = (function() { if (data) { categories = data; for (const i in data) { + if (!Object.hasOwn(data, i)) + continue; + const category = data[i]; const option = new Element("option"); option.set("value", category.name); diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 56260c19d..079be9f76 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -672,8 +672,11 @@ window.qBittorrent.DynamicTable = (function() { row = this.rows.get(rowId); row["data"] = data; - for (const x in data) + for (const x in data) { + if (!Object.hasOwn(data, x)) + continue; row["full_data"][x] = data[x]; + } }, getFilteredAndSortedRows: function() { diff --git a/src/webui/www/private/scripts/prop-peers.js b/src/webui/www/private/scripts/prop-peers.js index 2e3d23772..c3af13166 100644 --- a/src/webui/www/private/scripts/prop-peers.js +++ b/src/webui/www/private/scripts/prop-peers.js @@ -80,8 +80,10 @@ window.qBittorrent.PropPeers = (function() { syncTorrentPeersLastResponseId = response["rid"]; if (response["peers"]) { for (const key in response["peers"]) { - response["peers"][key]["rowId"] = key; + if (!Object.hasOwn(response["peers"], key)) + continue; + response["peers"][key]["rowId"] = key; torrentPeersTable.updateRowData(response["peers"][key]); } } diff --git a/src/webui/www/private/scripts/rename-files.js b/src/webui/www/private/scripts/rename-files.js index e32569969..23bc06438 100644 --- a/src/webui/www/private/scripts/rename-files.js +++ b/src/webui/www/private/scripts/rename-files.js @@ -199,6 +199,8 @@ window.qBittorrent.MultiRename = (function() { } // Replace named groups for (const namedGroup in match.groups) { + if (!Object.hasOwn(match.groups, namedGroup)) + continue; replacement = replaceGroup(replacement, `$${namedGroup}`, match.groups[namedGroup], "\\", false); } // Replace auxiliary variables diff --git a/src/webui/www/private/views/log.html b/src/webui/www/private/views/log.html index 624024b10..455b48fc7 100644 --- a/src/webui/www/private/views/log.html +++ b/src/webui/www/private/views/log.html @@ -240,8 +240,11 @@ }; const unload = () => { - for (const table in tableInfo) + for (const table in tableInfo) { + if (!Object.hasOwn(tableInfo, table)) + continue; resetTableTimer(table); + } }; const load = () => { diff --git a/src/webui/www/private/views/rss.html b/src/webui/www/private/views/rss.html index bfc408fb8..50cda410d 100644 --- a/src/webui/www/private/views/rss.html +++ b/src/webui/www/private/views/rss.html @@ -447,6 +447,9 @@ const flattenedResp = []; const recFlatten = (current, name = "", depth = 0, fullName = "") => { for (const child in current) { + if (!Object.hasOwn(current, child)) + continue; + const currentFullName = fullName ? (fullName + "\\" + child) : child; if (current[child].uid !== undefined) { current[child].name = child; @@ -671,8 +674,11 @@ }; const refreshAllFeeds = () => { - for (const feedEntry in feedData) + for (const feedEntry in feedData) { + if (!Object.hasOwn(feedData, feedEntry)) + continue; refreshFeed(feedEntry); + } }; const moveItem = (oldPath) => { diff --git a/src/webui/www/private/views/rssDownloader.html b/src/webui/www/private/views/rssDownloader.html index c5aa53b05..103b17c25 100644 --- a/src/webui/www/private/views/rssDownloader.html +++ b/src/webui/www/private/views/rssDownloader.html @@ -433,6 +433,9 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also onSuccess: (response) => { const combobox = $("assignCategoryCombobox"); for (const cat in response) { + if (!Object.hasOwn(response, cat)) + continue; + const option = document.createElement("option"); option.text = option.value = cat; combobox.add(option); @@ -476,6 +479,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also rssDownloaderRulesTable.clear(); let rowCount = 0; for (const rule in response) { + if (!Object.hasOwn(response, rule)) + continue; rssDownloaderRulesTable.updateRowData({ rowId: rowCount++, checked: response[rule].enabled, @@ -641,6 +646,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also rssDownloaderArticlesTable.clear(); let rowCount = 0; for (const feed in response) { + if (!Object.hasOwn(response, feed)) + continue; rssDownloaderArticlesTable.updateRowData({ rowId: rowCount++, name: feed,