From d03e7157084a912c1728ee9642eecaf6123b9fb1 Mon Sep 17 00:00:00 2001 From: Burak Yavuz Date: Tue, 14 Feb 2023 08:30:46 +0300 Subject: [PATCH 01/14] NSIS: Update Turkish translation PR #18552. --- dist/windows/installer-translations/turkish.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/windows/installer-translations/turkish.nsi b/dist/windows/installer-translations/turkish.nsi index 52703fcba..efe92115a 100644 --- a/dist/windows/installer-translations/turkish.nsi +++ b/dist/windows/installer-translations/turkish.nsi @@ -31,7 +31,7 @@ LangString inst_requires_64bit ${LANG_TURKISH} "Bu yükleyici sadece 64-bit Wind ;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7." LangString inst_requires_win7 ${LANG_TURKISH} "Bu qBittorrent sürümü en az Windows 7 gerektirir." ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 1809." -LangString inst_requires_win10 ${LANG_TURKISH} "This installer requires at least Windows 10 1809." +LangString inst_requires_win10 ${LANG_TURKISH} "Bu yükleyici en az Windows 10 1809 gerektirir." ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" LangString inst_uninstall_link_description ${LANG_TURKISH} "qBittorrent'i kaldır" From a63269e3e1cbcd825e61a481e9d2d788fb2dc916 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 15 Feb 2023 13:59:21 +0800 Subject: [PATCH 02/14] Migrate away from unsafe function MooTools More has CVE-2021-20088 and qbt is affected by it by using the unsafe function call `String.parseQueryString()`, so migrate away from it. PR #18554. --- src/webui/www/private/scripts/client.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index c1e3a2c68..a5b6c23f9 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -1289,11 +1289,11 @@ function registerMagnetHandler() { return; } - const hashParams = getHashParamsFromUrl(); - hashParams.download = ''; - - const templateHashString = Object.toQueryString(hashParams).replace('download=', 'download=%s'); + const hashString = location.hash ? location.hash.replace(/^#/, '') : ''; + const hashParams = new URLSearchParams(hashString); + hashParams.set('download', ''); + const templateHashString = hashParams.toString().replace('download=', 'download=%s'); const templateUrl = location.origin + location.pathname + location.search + '#' + templateHashString; @@ -1313,11 +1313,6 @@ function handleDownloadParam() { showDownloadPage([url]); } -function getHashParamsFromUrl() { - const hashString = location.hash ? location.hash.replace(/^#/, '') : ''; - return (hashString.length > 0) ? String.parseQueryString(hashString) : {}; -} - function closeWindows() { MochaUI.closeAll(); } From e9884b9513ee250e8edb2d6b165865b384ede84c Mon Sep 17 00:00:00 2001 From: shitcod3r <99270223+shitcod3r@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:58:06 +0500 Subject: [PATCH 03/14] NSIS: Add Uzbek translation PR #18568. --- dist/windows/installer-translations/uzbek.nsi | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/dist/windows/installer-translations/uzbek.nsi b/dist/windows/installer-translations/uzbek.nsi index 9afba66ff..53cb28ac7 100644 --- a/dist/windows/installer-translations/uzbek.nsi +++ b/dist/windows/installer-translations/uzbek.nsi @@ -1,62 +1,62 @@ ;Installer strings ;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)" -LangString inst_qbt_req ${LANG_UZBEK} "qBittorrent (required)" +LangString inst_qbt_req ${LANG_UZBEK} "qBittorrent (talab qilinadi)" ;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut" -LangString inst_dekstop ${LANG_UZBEK} "Create Desktop Shortcut" +LangString inst_dekstop ${LANG_UZBEK} "Ish Stolida Yorliq Yaratilsin" ;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut" -LangString inst_startmenu ${LANG_UZBEK} "Create Start Menu Shortcut" +LangString inst_startmenu ${LANG_UZBEK} "Boshlash Menyusida Yorliq Yaratilsin" ;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up" -LangString inst_startup ${LANG_UZBEK} "Start qBittorrent on Windows start up" +LangString inst_startup ${LANG_UZBEK} "qBittorrent Windows bilan birga ishga tushirilsin" ;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent" -LangString inst_torrent ${LANG_UZBEK} "Open .torrent files with qBittorrent" +LangString inst_torrent ${LANG_UZBEK} ".torrent fayllar qBittorrent bilan ochilsin" ;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent" -LangString inst_magnet ${LANG_UZBEK} "Open magnet links with qBittorrent" +LangString inst_magnet ${LANG_UZBEK} "Magnit havolalar qBittorrent bilan ochilsin" ;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule" -LangString inst_firewall ${LANG_UZBEK} "Add Windows Firewall rule" +LangString inst_firewall ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasi qoʻshilsin" ;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)" -LangString inst_pathlimit ${LANG_UZBEK} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)" +LangString inst_pathlimit ${LANG_UZBEK} "Windows yoʻl uzunligi cheklovi olib tashlansin (260 belgi MAX_PATH cheklovi, Windows 10 1607 va yuqorisi talab qilinadi)" ;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule" -LangString inst_firewallinfo ${LANG_UZBEK} "Adding Windows Firewall rule" +LangString inst_firewallinfo ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasini qoʻshish" ;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing." -LangString inst_warning ${LANG_UZBEK} "qBittorrent is running. Please close the application before installing." +LangString inst_warning ${LANG_UZBEK} "qBittorrent ishga tushgan. Iltimos, oʻrnatishdan oldin dasturni yoping." ;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact." -LangString inst_uninstall_question ${LANG_UZBEK} "Current version will be uninstalled. User settings and torrents will remain intact." +LangString inst_uninstall_question ${LANG_UZBEK} "Hozirgi versiya oʻchiriladi. Foydalanuvchi sozlamalari va torrentlar oʻzgarishsiz qoladi." ;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version." -LangString inst_unist ${LANG_UZBEK} "Uninstalling previous version." +LangString inst_unist ${LANG_UZBEK} "Oldingi versiyani oʻchirish." ;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent." -LangString launch_qbt ${LANG_UZBEK} "Launch qBittorrent." +LangString launch_qbt ${LANG_UZBEK} "qBittorrent ishga tushirilsin." ;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions." -LangString inst_requires_64bit ${LANG_UZBEK} "This installer works only in 64-bit Windows versions." +LangString inst_requires_64bit ${LANG_UZBEK} "Bu oʻrnatuvchi faqat Windows 64-bit versiyalarda ishlaydi." ;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7." -LangString inst_requires_win7 ${LANG_UZBEK} "This qBittorrent version requires at least Windows 7." +LangString inst_requires_win7 ${LANG_UZBEK} "qBittorrent bu versiyasi kamida Windows 7 talab qiladi." ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 1809." -LangString inst_requires_win10 ${LANG_UZBEK} "This installer requires at least Windows 10 1809." +LangString inst_requires_win10 ${LANG_UZBEK} "Bu oʻrnatuvchi kamida Windows 10 1809 talab qiladi." ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" -LangString inst_uninstall_link_description ${LANG_UZBEK} "Uninstall qBittorrent" +LangString inst_uninstall_link_description ${LANG_UZBEK} "qBittorrent oʻchirilsin" ;------------------------------------ ;Uninstaller strings ;LangString remove_files ${LANG_ENGLISH} "Remove files" -LangString remove_files ${LANG_UZBEK} "Remove files" +LangString remove_files ${LANG_UZBEK} "Fayllar oʻchirilsin" ;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts" -LangString remove_shortcuts ${LANG_UZBEK} "Remove shortcuts" +LangString remove_shortcuts ${LANG_UZBEK} "Yorliqlar oʻchirilsin" ;LangString remove_associations ${LANG_ENGLISH} "Remove file associations" -LangString remove_associations ${LANG_UZBEK} "Remove file associations" +LangString remove_associations ${LANG_UZBEK} "Fayl birlashmalari oʻchirilsin" ;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys" -LangString remove_registry ${LANG_UZBEK} "Remove registry keys" +LangString remove_registry ${LANG_UZBEK} "Reyester kalitlari oʻchirilsin" ;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files" -LangString remove_conf ${LANG_UZBEK} "Remove configuration files" +LangString remove_conf ${LANG_UZBEK} "Sozlama fayllari oʻchirilsin" ;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule" -LangString remove_firewall ${LANG_UZBEK} "Remove Windows Firewall rule" +LangString remove_firewall ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasi oʻchirilsin" ;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule" -LangString remove_firewallinfo ${LANG_UZBEK} "Removing Windows Firewall rule" +LangString remove_firewallinfo ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasini oʻchirish" ;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data" -LangString remove_cache ${LANG_UZBEK} "Remove torrents and cached data" +LangString remove_cache ${LANG_UZBEK} "Torrentlar va keshlangan maʼlumotlar oʻchirilsin" ;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling." -LangString uninst_warning ${LANG_UZBEK} "qBittorrent is running. Please close the application before uninstalling." +LangString uninst_warning ${LANG_UZBEK} "qBittorrent ishga tushgan. Iltimos, oʻchirishdan oldin dasturni yoping." ;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:" -LangString uninst_tor_warn ${LANG_UZBEK} "Not removing .torrent association. It is associated with:" +LangString uninst_tor_warn ${LANG_UZBEK} ".torrent birlashmasi oʻchirilmadi. U quyidagi bilan birlashgan:" ;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:" -LangString uninst_mag_warn ${LANG_UZBEK} "Not removing magnet association. It is associated with:" +LangString uninst_mag_warn ${LANG_UZBEK} "Magnit birlashmasi oʻchirilmadi. U quyidagi bilan birlashgan:" From 97a30218bcf9c1448423bbf2e5bef74caf498d6d Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Thu, 2 Feb 2023 06:16:32 +0300 Subject: [PATCH 04/14] Don't increase limits when prefetching metadata for added magnets Adjusting limits was made based on the belief that "forced" torrents (internally used for prefetching metadata) are still under limits, but ignore only the queue. This is not really the case. "Forced" torrents ignore the limits like "maximum active torrents/downloads", so adjusting limits is not required, and what's more, it really causes the problem of unexpectedly activated previously queued torrents when adding some magnet using "Add new torrent" dialog. PR #18503. Fixes #18490. --- src/base/bittorrent/sessionimpl.cpp | 35 ++--------------------------- src/base/bittorrent/sessionimpl.h | 3 --- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 25a8adfa5..d8df665b3 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1050,18 +1050,6 @@ void SessionImpl::setGlobalMaxSeedingMinutes(int minutes) } } -void SessionImpl::adjustLimits() -{ - if (isQueueingSystemEnabled()) - { - lt::settings_pack settingsPack; - // Internally increase the queue limits to ensure that the magnet is started - settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); - settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); - m_nativeSession->apply_settings(std::move(settingsPack)); - } -} - void SessionImpl::applyBandwidthLimits() { lt::settings_pack settingsPack; @@ -1502,16 +1490,6 @@ void SessionImpl::processBannedIPs(lt::ip_filter &filter) } } -int SessionImpl::adjustLimit(const int limit) const -{ - if (limit <= -1) - return limit; - // check for overflow: (limit + m_extraLimit) < std::numeric_limits::max() - return (m_extraLimit < (std::numeric_limits::max() - limit)) - ? (limit + m_extraLimit) - : std::numeric_limits::max(); -} - void SessionImpl::initMetrics() { const auto findMetricIndex = [](const char *name) -> int @@ -1713,10 +1691,8 @@ lt::settings_pack SessionImpl::loadLTSettings() const // Queueing System if (isQueueingSystemEnabled()) { - // Internally increase the queue limits to ensure that the magnet is started - settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); - settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); - + settingsPack.set_int(lt::settings_pack::active_downloads, maxActiveDownloads()); + settingsPack.set_int(lt::settings_pack::active_limit, maxActiveTorrents()); settingsPack.set_int(lt::settings_pack::active_seeds, maxActiveUploads()); settingsPack.set_bool(lt::settings_pack::dont_count_slow_torrents, ignoreSlowTorrentsForQueueing()); settingsPack.set_int(lt::settings_pack::inactive_down_rate, downloadRateForSlowTorrents() * 1024); // KiB to Bytes @@ -2290,8 +2266,6 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id) } #endif m_downloadedMetadata.erase(downloadedMetadataIter); - --m_extraLimit; - adjustLimits(); m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_files); return true; } @@ -2839,8 +2813,6 @@ bool SessionImpl::downloadMetadata(const MagnetUri &magnetUri) const auto altID = TorrentID::fromSHA1Hash(infoHash.v1()); m_downloadedMetadata.insert(altID); } - ++m_extraLimit; - adjustLimits(); return true; } @@ -5331,9 +5303,6 @@ void SessionImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert if (found) { const TorrentInfo metadata {*p->handle.torrent_file()}; - - --m_extraLimit; - adjustLimits(); m_nativeSession->remove_torrent(p->handle, lt::session::delete_files); emit metadataDownloaded(metadata); diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 3d0c3b08d..45b4bf2d8 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -475,9 +475,7 @@ namespace BitTorrent lt::settings_pack loadLTSettings() const; void applyNetworkInterfacesSettings(lt::settings_pack &settingsPack) const; void configurePeerClasses(); - int adjustLimit(int limit) const; void initMetrics(); - void adjustLimits(); void applyBandwidthLimits(); void processBannedIPs(lt::ip_filter &filter); QStringList getListeningIPs() const; @@ -668,7 +666,6 @@ namespace BitTorrent const bool m_wasPexEnabled = m_isPeXEnabled; int m_numResumeData = 0; - int m_extraLimit = 0; QVector m_additionalTrackerList; QVector m_excludedFileNamesRegExpList; From 8e81d44b3c33ab150791621861fe0d53e069ceaf Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Fri, 17 Feb 2023 07:12:56 +0300 Subject: [PATCH 05/14] Update the cached state once recheck is started We have to force update the cached state, otherwise someone will be able to get an incorrect one during the interval until the cached state is updated in a regular way. PR #18579. Closes #18559. --- src/base/bittorrent/torrentimpl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 67d0dabbe..596b339fc 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1441,6 +1441,10 @@ void TorrentImpl::forceRecheck() if (!hasMetadata()) return; m_nativeHandle.force_recheck(); + // We have to force update the cached state, otherwise someone will be able to get + // an incorrect one during the interval until the cached state is updated in a regular way. + m_nativeStatus.state = lt::torrent_status::checking_resume_data; + m_hasMissingFiles = false; m_unchecked = false; m_completedFiles.fill(false); From d40c7e88337d76a9dbb7ba892323e164e928e392 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 16 Feb 2023 16:10:08 +0800 Subject: [PATCH 06/14] GHA CI: speed up package installation on macOS Setup time is shortened by cutting down unnecessary operations. https://docs.brew.sh/Manpage#environment --- .github/workflows/ci_macos.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml index dd0de04ca..d15af6157 100644 --- a/.github/workflows/ci_macos.yaml +++ b/.github/workflows/ci_macos.yaml @@ -31,6 +31,9 @@ jobs: - name: Install dependencies run: | + export \ + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 \ + HOMEBREW_NO_INSTALL_CLEANUP=1 brew update > /dev/null brew install \ cmake ninja \ From 0bfe6ff64bff9cacc6fd9ee37166abecb3321f1e Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 16 Feb 2023 16:16:54 +0800 Subject: [PATCH 07/14] GHA CI: use least permission level `actions: write` is required by Chocobo1/setup-ccache-action. `pull-requests: write` is required by actions/stale. https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions --- .github/workflows/ci_file_health.yaml | 2 ++ .github/workflows/ci_macos.yaml | 3 +++ .github/workflows/ci_ubuntu.yaml | 3 +++ .github/workflows/ci_webui.yaml | 2 ++ .github/workflows/ci_windows.yaml | 3 +++ .github/workflows/coverity-scan.yml | 2 ++ .github/workflows/stale_bot.yaml | 3 +++ 7 files changed, 18 insertions(+) diff --git a/.github/workflows/ci_file_health.yaml b/.github/workflows/ci_file_health.yaml index a46290f53..eb151513c 100644 --- a/.github/workflows/ci_file_health.yaml +++ b/.github/workflows/ci_file_health.yaml @@ -2,6 +2,8 @@ name: CI - File health on: [pull_request, push] +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml index d15af6157..9559d5daa 100644 --- a/.github/workflows/ci_macos.yaml +++ b/.github/workflows/ci_macos.yaml @@ -2,6 +2,9 @@ name: CI - macOS on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 053077ef4..fb522bb8a 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -2,6 +2,9 @@ name: CI - Ubuntu on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_webui.yaml b/.github/workflows/ci_webui.yaml index 18d0e985c..335cfe6ad 100644 --- a/.github/workflows/ci_webui.yaml +++ b/.github/workflows/ci_webui.yaml @@ -2,6 +2,8 @@ name: CI - WebUI on: [pull_request, push] +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_windows.yaml b/.github/workflows/ci_windows.yaml index bca52a8e1..611c1cc2a 100644 --- a/.github/workflows/ci_windows.yaml +++ b/.github/workflows/ci_windows.yaml @@ -2,6 +2,9 @@ name: CI - Windows on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index ad243a915..22fbc478e 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -5,6 +5,8 @@ on: - cron: '0 0 1 * *' # Monthly (1st day of month at midnight) workflow_dispatch: # Mainly for testing. Don't forget the Coverity usage limits. +permissions: {} + jobs: coverity_scan: name: Scan diff --git a/.github/workflows/stale_bot.yaml b/.github/workflows/stale_bot.yaml index 4cb991b87..93fad6070 100644 --- a/.github/workflows/stale_bot.yaml +++ b/.github/workflows/stale_bot.yaml @@ -4,6 +4,9 @@ on: schedule: - cron: '0 0 * * *' +permissions: + pull-requests: write + jobs: stale: runs-on: ubuntu-latest From e31cf5ac232b8d7a98d26c8807cbd29f0f1ae91a Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 16 Feb 2023 16:20:05 +0800 Subject: [PATCH 08/14] GHA CI: revert "[CI Ubuntu] Strip installed components" For tester convenience, the binaries should ship with debug symbols. This reverts commit b8aa9e56092b54909b47d96ec4e9696261ccb892. --- .github/workflows/ci_ubuntu.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index fb522bb8a..89fcbe0a9 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -81,7 +81,7 @@ jobs: cmake --build build --target qbt_update_translations cmake --build build cmake --build build --target check - DESTDIR="qbittorrent" cmake --install build --strip + DESTDIR="qbittorrent" cmake --install build - name: Build qBittorrent (Qt6) if: ${{ startsWith(matrix.qt_version, 6) }} @@ -100,7 +100,7 @@ jobs: cmake --build build --target qbt_update_translations cmake --build build cmake --build build --target check - DESTDIR="qbittorrent" cmake --install build --strip + DESTDIR="qbittorrent" cmake --install build - name: Prepare build artifacts run: | From 792301dfe4eea54c7a7f5aac81f10d1e043e5cd6 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 16 Feb 2023 16:26:38 +0800 Subject: [PATCH 09/14] GHA CI: don't overwrite system default compile flags System might have some default compile flags which are crucial for security hardening so we should append our flags instead of overwriting them. --- .github/workflows/ci_macos.yaml | 4 ++-- .github/workflows/ci_ubuntu.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml index 9559d5daa..87a3726d6 100644 --- a/.github/workflows/ci_macos.yaml +++ b/.github/workflows/ci_macos.yaml @@ -86,11 +86,11 @@ jobs: - name: Build qBittorrent (Qt5) if: ${{ startsWith(matrix.qt_version, 5) }} run: | + CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DBOOST_ROOT="${{ env.boost_path }}" \ -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \ @@ -104,11 +104,11 @@ jobs: - name: Build qBittorrent (Qt6) if: ${{ startsWith(matrix.qt_version, 6) }} run: | + CXXFLAGS="$CXXFLAGS -Wno-gnu-zero-variadic-macro-arguments -Werror -Wno-error=deprecated-declarations" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Wno-gnu-zero-variadic-macro-arguments -Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DBOOST_ROOT="${{ env.boost_path }}" \ -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \ diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 89fcbe0a9..02d857782 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -68,11 +68,11 @@ jobs: - name: Build qBittorrent (Qt5) if: ${{ startsWith(matrix.qt_version, 5) }} run: | + CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DTESTING=ON \ @@ -86,11 +86,11 @@ jobs: - name: Build qBittorrent (Qt6) if: ${{ startsWith(matrix.qt_version, 6) }} run: | + CXXFLAGS="$CXXFLAGS -Werror" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DQT6=ON \ From 35f7e1c896218baff6e4d5b7520e3624a872db89 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 16 Feb 2023 16:31:48 +0800 Subject: [PATCH 10/14] GHA CI: compress debug symbols The result binary is smaller. --- .github/workflows/ci_macos.yaml | 2 ++ .github/workflows/ci_ubuntu.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml index 87a3726d6..181331069 100644 --- a/.github/workflows/ci_macos.yaml +++ b/.github/workflows/ci_macos.yaml @@ -87,6 +87,7 @@ jobs: if: ${{ startsWith(matrix.qt_version, 5) }} run: | CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ @@ -105,6 +106,7 @@ jobs: if: ${{ startsWith(matrix.qt_version, 6) }} run: | CXXFLAGS="$CXXFLAGS -Wno-gnu-zero-variadic-macro-arguments -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 02d857782..2d1f1b8e3 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -69,6 +69,7 @@ jobs: if: ${{ startsWith(matrix.qt_version, 5) }} run: | CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ @@ -87,6 +88,7 @@ jobs: if: ${{ startsWith(matrix.qt_version, 6) }} run: | CXXFLAGS="$CXXFLAGS -Werror" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ From 632d33b266ff581e6b7b6f790f357c04ef64ef9e Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Wed, 1 Feb 2023 02:23:12 +0200 Subject: [PATCH 11/14] Blacklist bad ciphers for TLS in the server Prevents the ROBOT attack. Closes #18483 --- src/base/http/server.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index f53e437d7..d2b6ebf71 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -56,10 +56,33 @@ namespace QList safeCipherList() { const QStringList badCiphers {u"idea"_qs, u"rc4"_qs}; + // Contains Ciphersuites that use RSA for the Key Exchange but they don't mention it in their name + const QStringList badRSAShorthandSuites { + u"AES256-GCM-SHA384"_qs, u"AES128-GCM-SHA256"_qs, u"AES256-SHA256"_qs, + u"AES128-SHA256"_qs, u"AES256-SHA"_qs, u"AES128-SHA"_qs}; + // Contains Ciphersuites that use AES CBC mode but they don't mention it in their name + const QStringList badAESShorthandSuites { + u"ECDHE-ECDSA-AES256-SHA384"_qs, u"ECDHE-RSA-AES256-SHA384"_qs, u"DHE-RSA-AES256-SHA256"_qs, + u"ECDHE-ECDSA-AES128-SHA256"_qs, u"ECDHE-RSA-AES128-SHA256"_qs, u"DHE-RSA-AES128-SHA256"_qs, + u"ECDHE-ECDSA-AES256-SHA"_qs, u"ECDHE-RSA-AES256-SHA"_qs, u"DHE-RSA-AES256-SHA"_qs, + u"ECDHE-ECDSA-AES128-SHA"_qs, u"ECDHE-RSA-AES128-SHA"_qs, u"DHE-RSA-AES128-SHA"_qs}; const QList allCiphers {QSslConfiguration::supportedCiphers()}; QList safeCiphers; - std::copy_if(allCiphers.cbegin(), allCiphers.cend(), std::back_inserter(safeCiphers), [&badCiphers](const QSslCipher &cipher) + std::copy_if(allCiphers.cbegin(), allCiphers.cend(), std::back_inserter(safeCiphers), + [&badCiphers, &badRSAShorthandSuites, &badAESShorthandSuites](const QSslCipher &cipher) { + const QString name = cipher.name(); + if (name.contains(u"-cbc-"_qs, Qt::CaseInsensitive) // AES CBC mode is considered vulnerable to BEAST attack + || name.startsWith(u"adh-"_qs, Qt::CaseInsensitive) // Key Exchange: Diffie-Hellman, doesn't support Perfect Forward Secrecy + || name.startsWith(u"aecdh-"_qs, Qt::CaseInsensitive) // Key Exchange: Elliptic Curve Diffie-Hellman, doesn't support Perfect Forward Secrecy + || name.startsWith(u"psk-"_qs, Qt::CaseInsensitive) // Key Exchange: Pre-Shared Key, doesn't support Perfect Forward Secrecy + || name.startsWith(u"rsa-"_qs, Qt::CaseInsensitive) // Key Exchange: Rivest Shamir Adleman (RSA), doesn't support Perfect Forward Secrecy + || badRSAShorthandSuites.contains(name, Qt::CaseInsensitive) + || badAESShorthandSuites.contains(name, Qt::CaseInsensitive)) + { + return false; + } + return std::none_of(badCiphers.cbegin(), badCiphers.cend(), [&cipher](const QString &badCipher) { return cipher.name().contains(badCipher, Qt::CaseInsensitive); From abd1ab5539372d9910df26a3bb0022a8979de4ec Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Wed, 1 Feb 2023 02:26:59 +0200 Subject: [PATCH 12/14] Support TLS 1.2+ only in the server Closes #18122 --- src/base/http/server.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index d2b6ebf71..e85750c53 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -101,6 +101,7 @@ Server::Server(IRequestHandler *requestHandler, QObject *parent) setProxy(QNetworkProxy::NoProxy); QSslConfiguration sslConf {QSslConfiguration::defaultConfiguration()}; + sslConf.setProtocol(QSsl::TlsV1_2OrLater); sslConf.setCiphers(safeCipherList()); QSslConfiguration::setDefaultConfiguration(sslConf); From df08bd331c533986081b22cfe789994e0701d436 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Tue, 14 Feb 2023 08:26:08 +0300 Subject: [PATCH 13/14] Prevent precise timers from being used when unnecessary The implementation of QTimer::singleShot() uses Qt::PreciseTimer if interval is less than 2 seconds. This isn't mentioned in the docs. Qt::PreciseTimer increases the system's timer resolution which negatively affects power consumption. PR #18555. Closes #18350. --- src/app/main.cpp | 2 +- src/base/bittorrent/sessionimpl.cpp | 2 +- src/base/torrentfileswatcher.cpp | 2 +- src/webui/api/appcontroller.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index bbb293479..fb7d5d12a 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -283,7 +283,7 @@ void showSplashScreen() painter.drawText(224 - painter.fontMetrics().horizontalAdvance(version), 270, version); QSplashScreen *splash = new QSplashScreen(splashImg); splash->show(); - QTimer::singleShot(1500ms, splash, &QObject::deleteLater); + QTimer::singleShot(1500ms, Qt::CoarseTimer, splash, &QObject::deleteLater); qApp->processEvents(); } #endif // DISABLE_GUI diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index d8df665b3..59a1eec9d 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -4929,7 +4929,7 @@ void SessionImpl::enqueueRefresh() { Q_ASSERT(!m_refreshEnqueued); - QTimer::singleShot(refreshInterval(), this, [this] () + QTimer::singleShot(refreshInterval(), Qt::CoarseTimer, this, [this] { m_nativeSession->post_torrent_updates(); m_nativeSession->post_session_stats(); diff --git a/src/base/torrentfileswatcher.cpp b/src/base/torrentfileswatcher.cpp index 11b04c953..1e56ffbb9 100644 --- a/src/base/torrentfileswatcher.cpp +++ b/src/base/torrentfileswatcher.cpp @@ -503,7 +503,7 @@ void TorrentFilesWatcher::Worker::removeWatchedFolder(const Path &path) void TorrentFilesWatcher::Worker::scheduleWatchedFolderProcessing(const Path &path) { - QTimer::singleShot(2s, this, [this, path]() + QTimer::singleShot(2s, Qt::CoarseTimer, this, [this, path] { processWatchedFolder(path); }); diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index e0ddc7d5b..f7a723af8 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -94,7 +94,7 @@ void AppController::shutdownAction() // Special handling for shutdown, we // need to reply to the Web UI before // actually shutting down. - QTimer::singleShot(100ms, qApp, []() + QTimer::singleShot(100ms, Qt::CoarseTimer, qApp, [] { QCoreApplication::exit(); }); From 36364121ba0ea1974017ca836324956db77611ff Mon Sep 17 00:00:00 2001 From: brvphoenix <30111323+brvphoenix@users.noreply.github.com> Date: Sun, 19 Feb 2023 22:02:59 +0800 Subject: [PATCH 14/14] GHA CI: Add missing dependencies PR #18596. --- .github/workflows/ci_ubuntu.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 2d1f1b8e3..f9b0d4181 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -33,7 +33,7 @@ jobs: sudo apt update sudo apt install \ build-essential cmake ninja-build pkg-config \ - libboost-dev libssl-dev zlib1g-dev + libboost-dev libssl-dev libxkbcommon-x11-dev zlib1g-dev - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1