From ae4eafcce2e0ead0334c5113b92d29f1600cdad5 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 f99fd7b5db..242ae4542f 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 a01b920f0f..dcff02f565 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 @@ class EditWidgetIcons : public QWidget 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 d71b3e39e4..e57bc97d65 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()