From 84f5adb24acb9ea85f55b2f959b3bfe9faf9015d Mon Sep 17 00:00:00 2001 From: Kyle Kneitinger Date: Sun, 17 Mar 2019 06:45:37 -0700 Subject: [PATCH] Remediate errors in various favicon fetch scenarios (#2779) Fixes stuck "Download favicon" button on icon download attempts for IP address hosts by skipping attempts to get 2nd level domain resources (which resulted in calls to 0.0.0.). Fixes some cases when DuckDuckGo fallback fails to find icon of >2-level domains, by adding a request to a DDG URL based on entry's 2nd level domain. Repurposes EditWidgetIcons' private fetchCanceled slot (which as of #2439, is unused by any code) into public abortRequests slot, which is connected to the entry edit widget's accepted and rejected signals (in other words, Ok or Cancel was pressed). --- src/gui/EditWidgetIcons.cpp | 36 +++++++++++++++++++++++++------ src/gui/EditWidgetIcons.h | 3 +-- src/gui/entry/EditEntryWidget.cpp | 2 ++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/gui/EditWidgetIcons.cpp b/src/gui/EditWidgetIcons.cpp index f99fd7b5..242ae454 100644 --- a/src/gui/EditWidgetIcons.cpp +++ b/src/gui/EditWidgetIcons.cpp @@ -30,6 +30,7 @@ #include "gui/MessageBox.h" #ifdef WITH_XC_NETWORKING +#include #include #include #endif @@ -195,13 +196,27 @@ void EditWidgetIcons::downloadFavicon() m_urlsToTry.clear(); QString fullyQualifiedDomain = m_url.host(); - QString secondLevelDomain = getSecondLevelDomain(m_url); - // Attempt to simply load the favicon.ico file - if (fullyQualifiedDomain != secondLevelDomain) { - m_urlsToTry.append(QUrl(m_url.scheme() + "://" + fullyQualifiedDomain + "/favicon.ico")); + m_urlsToTry.append(QUrl(m_url.scheme() + "://" + fullyQualifiedDomain + "/favicon.ico")); + + // Determine if host portion of URL is an IP address by resolving it and + // searching for a match with the returned address(es). + bool hostIsIp = false; + QList hostAddressess = QHostInfo::fromName(fullyQualifiedDomain).addresses(); + for (auto addr : hostAddressess) { + if (addr.toString() == fullyQualifiedDomain) { + hostIsIp = true; + } + } + + if (!hostIsIp) { + QString secondLevelDomain = getSecondLevelDomain(m_url); + + // Attempt to simply load the favicon.ico file + if (fullyQualifiedDomain != secondLevelDomain) { + m_urlsToTry.append(QUrl(m_url.scheme() + "://" + secondLevelDomain + "/favicon.ico")); + } } - m_urlsToTry.append(QUrl(m_url.scheme() + "://" + secondLevelDomain + "/favicon.ico")); // Try to use alternative fallback URL, if enabled if (config()->get("security/IconDownloadFallback", false).toBool()) { @@ -209,6 +224,15 @@ void EditWidgetIcons::downloadFavicon() fallbackUrl.setPath("/ip3/" + QUrl::toPercentEncoding(fullyQualifiedDomain) + ".ico"); m_urlsToTry.append(fallbackUrl); + + if (!hostIsIp) { + QString secondLevelDomain = getSecondLevelDomain(m_url); + + if (fullyQualifiedDomain != secondLevelDomain) { + fallbackUrl.setPath("/ip3/" + QUrl::toPercentEncoding(secondLevelDomain) + ".ico"); + m_urlsToTry.append(fallbackUrl); + } + } } startFetchFavicon(m_urlsToTry.takeFirst()); @@ -276,7 +300,7 @@ void EditWidgetIcons::fetchFinished() #endif } -void EditWidgetIcons::fetchCanceled() +void EditWidgetIcons::abortRequests() { #ifdef WITH_XC_NETWORKING if (m_reply) { diff --git a/src/gui/EditWidgetIcons.h b/src/gui/EditWidgetIcons.h index a01b920f..dcff02f5 100644 --- a/src/gui/EditWidgetIcons.h +++ b/src/gui/EditWidgetIcons.h @@ -19,7 +19,6 @@ #ifndef KEEPASSX_EDITWIDGETICONS_H #define KEEPASSX_EDITWIDGETICONS_H -#include #include #include #include @@ -66,6 +65,7 @@ public: public slots: void setUrl(const QString& url); + void abortRequests(); signals: void messageEditEntry(QString, MessageWidget::MessageType); @@ -77,7 +77,6 @@ private slots: void startFetchFavicon(const QUrl& url); void fetchFinished(); void fetchReadyRead(); - void fetchCanceled(); void addCustomIconFromFile(); bool addCustomIcon(const QImage& icon); void removeCustomIcon(); diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index d71b3e39..e57bc97d 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -194,6 +194,8 @@ void EditEntryWidget::setupAdvanced() void EditEntryWidget::setupIcon() { addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_iconsWidget); + connect(this, SIGNAL(accepted()), m_iconsWidget, SLOT(abortRequests())); + connect(this, SIGNAL(rejected()), m_iconsWidget, SLOT(abortRequests())); } void EditEntryWidget::setupAutoType()