[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#859632: marked as done (unblock: kio/5.28.0-2)



Your message dated Wed, 05 Apr 2017 12:49:00 +0000
with message-id <b1143a1c-b9d1-7d46-26a5-c7165366d377@thykier.net>
and subject line Re: Bug#859632: unblock: kio/5.28.0-2
has caused the Debian Bug report #859632,
regarding unblock: kio/5.28.0-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
859632: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859632
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Dear release team,

I've backported some upstream fixes in kio for stretch that I consider 
worthwhile, at least one of the changes fix the CVE-2017-6410 (#856889):
 Sanitize URLs before passing them to FindProxyForURL (f9d0cb4)

Two patches to fix a memory leak:
 + Fix memleak in KDynamicJobTracker, KWidgetJobTracker needs QApplication
   (3261c84)
 + Fix KDynamicJobTrackerTest for linkers dropping linked libs w/o used
   symbols (17be5b1)
   -> fixes the test introduced in the previous patch

Six of the rest fix five user facing issues:
 + File dialog fixes
   + Never stretch the last (=date) column in the file dialog (9a997fb)
     KDE#312747
   + Also change the resize mode the other way (a4085b7)
 + Allow uppercase checksums matching in Checksums tab (d1c652a)
   KDE#372518
 + kssl: Ensure user certificate directory has been created before use
   (d06e40b) KDE#342958
 + Fix parsing of directories listing on a specific ftp server (b158255)
   KDE#375610
 + kioexec: fix support for --suggestedfilename (fff13bf)

And two internal changes with three patches of parts that affect other 
applications:
 + ForwardingSlaveBase: fix passing of Overwrite flag to kio_desktop (7f2abde)
   KDE#360487
   -> affects plasma's folder view
 + Fix another clear porting bug in ForwardingSlaveBase (9d5d9ea)
   -> similar to the previous patch
 + keep query encoding when HTTP Proxy is used (c3fd249)
   -> affects KTorrent when using a proxy

I've uploaded 5.28.0-2 with these changes, and it has successfully built in 
all the release architectures.

I'm attaching the corresponding debdiff.

Happy hacking,

Please unblock package kio

unblock kio/5.28.0-2

-- System Information:
Debian Release: 9.0
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'testing-debug'), (500, 'testing'), (500, 'stable'), (50, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386, armhf

Kernel: Linux 4.9.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)
diff -Nru kio-5.28.0/debian/changelog kio-5.28.0/debian/changelog
--- kio-5.28.0/debian/changelog	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/changelog	2017-04-05 10:10:59.000000000 +0200
@@ -1,3 +1,29 @@
+kio (5.28.0-2) unstable; urgency=medium
+
+  * Add new upstream patches, to improve file dialog's list:
+    Never-stretch-the-last-date-column-in-the-file-dialog.patch,
+    Also-change-the-resize-mode-the-other-way.patch and
+  * Add new upstream patch:
+    Allow-uppercase-checksums-matching-in-Checksums-tab.patch
+  * Add new upstream patchs to fix the way the flags are being passed:
+    ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch,
+    ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch
+  * Add new upstream patch:
+    kssl-Ensure-user-certificate-directory-has-been-created-b.patch
+  * Add new upstream patch:
+    Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch
+  * Add new upstream patch:
+    Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch
+  * Add new upstream patch for CVE-2017-6410:
+    Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch.
+    Thanks to Salvatore Bonaccorso for reporting (Closes: 856889)
+  * Add new upstream patch: keep-query-encoding-when-HTTP-Proxy-is-used.patch
+  * Add new upstream patch: kioexec-fix-support-for-suggestedfilename.patch
+  * Add new upstream patch, to fix the testsuite:
+    Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch
+
+ -- Maximiliano Curia <maxy@debian.org>  Wed, 05 Apr 2017 10:10:59 +0200
+
 kio (5.28.0-1) unstable; urgency=medium
 
   [ Automatic packaging ]
diff -Nru kio-5.28.0/debian/patches/Allow-uppercase-checksums-matching-in-Checksums-tab.patch kio-5.28.0/debian/patches/Allow-uppercase-checksums-matching-in-Checksums-tab.patch
--- kio-5.28.0/debian/patches/Allow-uppercase-checksums-matching-in-Checksums-tab.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Allow-uppercase-checksums-matching-in-Checksums-tab.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,69 @@
+From: Elvis Angelaccio <elvis.angelaccio@kde.org>
+Date: Wed, 16 Nov 2016 13:30:01 +0100
+Subject: Allow uppercase checksums matching in Checksums tab
+
+While the checksum in cache is always guaranteed to be lowercase, the
+one from the line edit may be uppercase. If we make it lowercase
+*before* processing it, we can also simplify the regexes.
+
+REVIEW: 129415
+BUG: 372518
+FIXED-IN: 5.29
+---
+ src/widgets/kpropertiesdialog.cpp | 11 +++++++----
+ src/widgets/kpropertiesdialog_p.h |  3 +++
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/src/widgets/kpropertiesdialog.cpp b/src/widgets/kpropertiesdialog.cpp
+index d246b056..8e8861d2 100644
+--- a/src/widgets/kpropertiesdialog.cpp
++++ b/src/widgets/kpropertiesdialog.cpp
+@@ -2662,7 +2662,10 @@ KChecksumsPlugin::KChecksumsPlugin(KPropertiesDialog *dialog)
+     d->m_ui.sha1CopyButton->hide();
+     d->m_ui.sha256CopyButton->hide();
+ 
+-    connect(d->m_ui.lineEdit, &QLineEdit::textChanged, this, &KChecksumsPlugin::slotVerifyChecksum);
++    connect(d->m_ui.lineEdit, &QLineEdit::textChanged, this, [=](const QString &text) {
++        slotVerifyChecksum(text.toLower());
++    });
++
+     connect(d->m_ui.md5Button, &QPushButton::clicked, this, &KChecksumsPlugin::slotShowMd5);
+     connect(d->m_ui.sha1Button, &QPushButton::clicked, this, &KChecksumsPlugin::slotShowSha1);
+     connect(d->m_ui.sha256Button, &QPushButton::clicked, this, &KChecksumsPlugin::slotShowSha256);
+@@ -2813,19 +2816,19 @@ void KChecksumsPlugin::slotVerifyChecksum(const QString &input)
+ 
+ bool KChecksumsPlugin::isMd5(const QString &input)
+ {
+-    QRegularExpression regex(QStringLiteral("^[a-fA-F0-9]{32}$"));
++    QRegularExpression regex(QStringLiteral("^[a-f0-9]{32}$"));
+     return regex.match(input).hasMatch();
+ }
+ 
+ bool KChecksumsPlugin::isSha1(const QString &input)
+ {
+-    QRegularExpression regex(QStringLiteral("^[a-fA-F0-9]{40}$"));
++    QRegularExpression regex(QStringLiteral("^[a-f0-9]{40}$"));
+     return regex.match(input).hasMatch();
+ }
+ 
+ bool KChecksumsPlugin::isSha256(const QString &input)
+ {
+-    QRegularExpression regex(QStringLiteral("^[a-fA-F0-9]{64}$"));
++    QRegularExpression regex(QStringLiteral("^[a-f0-9]{64}$"));
+     return regex.match(input).hasMatch();
+ }
+ 
+diff --git a/src/widgets/kpropertiesdialog_p.h b/src/widgets/kpropertiesdialog_p.h
+index 8ad19e69..45df38c1 100644
+--- a/src/widgets/kpropertiesdialog_p.h
++++ b/src/widgets/kpropertiesdialog_p.h
+@@ -176,6 +176,9 @@ private Q_SLOTS:
+     void slotShowMd5();
+     void slotShowSha1();
+     void slotShowSha256();
++    /**
++     * Compare @p input (required to be lowercase) with the checksum in cache.
++     */
+     void slotVerifyChecksum(const QString &input);
+ 
+ private:
diff -Nru kio-5.28.0/debian/patches/Also-change-the-resize-mode-the-other-way.patch kio-5.28.0/debian/patches/Also-change-the-resize-mode-the-other-way.patch
--- kio-5.28.0/debian/patches/Also-change-the-resize-mode-the-other-way.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Also-change-the-resize-mode-the-other-way.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,21 @@
+From: Andreas Hartmetz <ahartmetz@gmail.com>
+Date: Sat, 12 Nov 2016 18:46:20 +0100
+Subject: Also change the resize mode the other way...
+
+---
+ src/filewidgets/kdiroperatordetailview.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/filewidgets/kdiroperatordetailview.cpp b/src/filewidgets/kdiroperatordetailview.cpp
+index 491aea57..32e82183 100644
+--- a/src/filewidgets/kdiroperatordetailview.cpp
++++ b/src/filewidgets/kdiroperatordetailview.cpp
+@@ -91,6 +91,8 @@ bool KDirOperatorDetailView::setViewMode(KFile::FileView viewMode)
+     // using KDirOperator in horizontally limited parts of an app.
+     if (tree && m_hideDetailColumns) {
+         header()->setSectionResizeMode(QHeaderView::ResizeToContents);
++    } else {
++        header()->setSectionResizeMode(QHeaderView::Interactive);
+     }
+ 
+     return true;
diff -Nru kio-5.28.0/debian/patches/Fix-another-clear-porting-bug-in-ForwardingSlaveBase.patch kio-5.28.0/debian/patches/Fix-another-clear-porting-bug-in-ForwardingSlaveBase.patch
--- kio-5.28.0/debian/patches/Fix-another-clear-porting-bug-in-ForwardingSlaveBase.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Fix-another-clear-porting-bug-in-ForwardingSlaveBase.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,23 @@
+From: David Faure <faure@kde.org>
+Date: Sun, 1 Jan 2017 13:38:30 +0100
+Subject: Fix another clear porting bug in ForwardingSlaveBase
+
+---
+ src/core/forwardingslavebase.cpp | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/core/forwardingslavebase.cpp b/src/core/forwardingslavebase.cpp
+index 0a16c2ef..12fa5f54 100644
+--- a/src/core/forwardingslavebase.cpp
++++ b/src/core/forwardingslavebase.cpp
+@@ -321,9 +321,7 @@ void ForwardingSlaveBase::copy(const QUrl &src, const QUrl &dest,
+     if (!d->internalRewriteUrl(src, new_src)) {
+         error(KIO::ERR_DOES_NOT_EXIST, src.toDisplayString());
+     } else if (d->internalRewriteUrl(dest, new_dest)) {
+-        // Are you sure you want to display here a ProgressInfo ???
+-        KIO::Job *job = KIO::file_copy(new_src, new_dest, permissions,
+-                                       (flags & (~Overwrite) & (~HideProgressInfo)));
++        KIO::Job *job = KIO::file_copy(new_src, new_dest, permissions, flags | HideProgressInfo);
+         d->connectJob(job);
+ 
+         d->eventLoop.exec();
diff -Nru kio-5.28.0/debian/patches/fix_hurd_build.patch kio-5.28.0/debian/patches/fix_hurd_build.patch
--- kio-5.28.0/debian/patches/fix_hurd_build.patch	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/fix_hurd_build.patch	2017-04-05 10:10:59.000000000 +0200
@@ -13,7 +13,7 @@
  2 files changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/src/ioslaves/file/file.cpp b/src/ioslaves/file/file.cpp
-index b4fd7f2..db48b29 100644
+index b4fd7f20..db48b295 100644
 --- a/src/ioslaves/file/file.cpp
 +++ b/src/ioslaves/file/file.cpp
 @@ -340,7 +340,7 @@ void FileProtocol::get(const QUrl &url)
@@ -26,7 +26,7 @@
      posix_fadvise(f.handle(), 0, 0, POSIX_FADV_SEQUENTIAL);
  #endif
 diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp
-index d901a63..ed86549 100644
+index d901a63d..ed86549f 100644
 --- a/src/ioslaves/file/file_unix.cpp
 +++ b/src/ioslaves/file/file_unix.cpp
 @@ -128,7 +128,7 @@ void FileProtocol::copy(const QUrl &srcUrl, const QUrl &destUrl,
diff -Nru kio-5.28.0/debian/patches/Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch kio-5.28.0/debian/patches/Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch
--- kio-5.28.0/debian/patches/Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,31 @@
+From: "Friedrich W. H. Kossebau" <kossebau@kde.org>
+Date: Fri, 13 Jan 2017 01:25:54 +0100
+Subject: Fix KDynamicJobTrackerTest for linkers dropping linked libs w/o used
+ symbols
+
+---
+ autotests/kdynamicjobtrackernowidgetstest.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/autotests/kdynamicjobtrackernowidgetstest.cpp b/autotests/kdynamicjobtrackernowidgetstest.cpp
+index a8dbee05..5f6b88e5 100644
+--- a/autotests/kdynamicjobtrackernowidgetstest.cpp
++++ b/autotests/kdynamicjobtrackernowidgetstest.cpp
+@@ -20,6 +20,7 @@
+ #include <KIO/JobTracker>
+ #include <KJobTrackerInterface>
+ #include <KJob>
++#include <KFile>
+ 
+ #include <QtTest>
+ #include <QEventLoop>
+@@ -48,6 +49,9 @@ private Q_SLOTS:
+ 
+ void KDynamicJobTrackerTest::testNoCrashWithoutQWidgetsPossible()
+ {
++    // dummy call: need to use some symbol from KIOWidgets so linkers do not drop linking to it
++    KFile::isDefaultView(KFile::Default);
++
+     // simply linking to KIOWidgets results in KDynamicJobTracker installing itself as KIO's jobtracker
+     KJobTrackerInterface* jobtracker = KIO::getJobTracker();
+     QCOMPARE(jobtracker->metaObject()->className(), "KDynamicJobTracker");
diff -Nru kio-5.28.0/debian/patches/fix_kfreebsd_build kio-5.28.0/debian/patches/fix_kfreebsd_build
--- kio-5.28.0/debian/patches/fix_kfreebsd_build	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/fix_kfreebsd_build	2017-04-05 10:10:59.000000000 +0200
@@ -8,7 +8,7 @@
  1 file changed, 5 insertions(+), 1 deletion(-)
 
 diff --git a/src/widgets/kpropertiesdialog.cpp b/src/widgets/kpropertiesdialog.cpp
-index 18c8479..d246b05 100644
+index 18c8479b..d246b056 100644
 --- a/src/widgets/kpropertiesdialog.cpp
 +++ b/src/widgets/kpropertiesdialog.cpp
 @@ -81,6 +81,10 @@
diff -Nru kio-5.28.0/debian/patches/Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch kio-5.28.0/debian/patches/Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch
--- kio-5.28.0/debian/patches/Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,236 @@
+From: "Friedrich W. H. Kossebau" <kossebau@kde.org>
+Date: Thu, 5 Jan 2017 03:08:45 +0100
+Subject: Fix memleak in KDynamicJobTracker,
+ KWidgetJobTracker needs QApplication
+
+Summary:
+KDynamicJobTracker was not cleaning up its internal job tracking
+data structure on finished jobs.
+Also was it trying to create a KWidgetJobTracker even if there
+was no QApplication instance.
+
+Reviewers: #frameworks, kfunk
+
+Reviewed By: kfunk
+
+Subscribers: kfunk
+
+Tags: #frameworks
+
+Differential Revision: https://phabricator.kde.org/D3977
+---
+ autotests/CMakeLists.txt                      |  1 +
+ autotests/kdynamicjobtrackernowidgetstest.cpp | 69 ++++++++++++++++++++++++
+ src/widgets/kdynamicjobtracker.cpp            | 77 +++++++++++++++++++--------
+ 3 files changed, 124 insertions(+), 23 deletions(-)
+ create mode 100644 autotests/kdynamicjobtrackernowidgetstest.cpp
+
+diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt
+index 436b5d95..0e2d252a 100644
+--- a/autotests/CMakeLists.txt
++++ b/autotests/CMakeLists.txt
+@@ -68,6 +68,7 @@ if (TARGET KF5::KIOWidgets)
+ ecm_add_tests(
+  clipboardupdatertest.cpp
+  dropjobtest.cpp
++ kdynamicjobtrackernowidgetstest.cpp
+  krununittest.cpp
+  kdirlistertest.cpp
+  kdirmodeltest.cpp
+diff --git a/autotests/kdynamicjobtrackernowidgetstest.cpp b/autotests/kdynamicjobtrackernowidgetstest.cpp
+new file mode 100644
+index 00000000..a8dbee05
+--- /dev/null
++++ b/autotests/kdynamicjobtrackernowidgetstest.cpp
+@@ -0,0 +1,69 @@
++/* This file is part of the KDE project
++   Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
++
++   This library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Library General Public
++   License as published by the Free Software Foundation; either
++   version 2 of the License, or (at your option) any later version.
++
++   This library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public License
++   along with this library; see the file COPYING.LIB.  If not, write to
++   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.
++ */
++
++#include <KIO/JobTracker>
++#include <KJobTrackerInterface>
++#include <KJob>
++
++#include <QtTest>
++#include <QEventLoop>
++
++// widget is shown with hardcoded delay of 500 ms by KWidgetJobTracker
++static const int testJobRunningTime = 600;
++
++class TestJob : public KJob
++{
++    Q_OBJECT
++public:
++    void start() Q_DECL_OVERRIDE { QTimer::singleShot(testJobRunningTime, this, &TestJob::doEmit); }
++
++private Q_SLOTS:
++    void doEmit() { emitResult(); }
++};
++
++
++class KDynamicJobTrackerTest : public QObject
++{
++    Q_OBJECT
++
++private Q_SLOTS:
++    void testNoCrashWithoutQWidgetsPossible();
++};
++
++void KDynamicJobTrackerTest::testNoCrashWithoutQWidgetsPossible()
++{
++    // simply linking to KIOWidgets results in KDynamicJobTracker installing itself as KIO's jobtracker
++    KJobTrackerInterface* jobtracker = KIO::getJobTracker();
++    QCOMPARE(jobtracker->metaObject()->className(), "KDynamicJobTracker");
++
++    TestJob *job = new TestJob;
++
++    jobtracker->registerJob(job);
++
++    job->start();
++    QEventLoop loop;
++    connect(job, &KJob::result, &loop, &QEventLoop::quit);
++    loop.exec();
++    // if we are here, no crash has happened due to QWidgets tried to be used -> success
++}
++
++// GUILESS, so QWidgets are not possible
++QTEST_GUILESS_MAIN(KDynamicJobTrackerTest)
++
++#include "kdynamicjobtrackernowidgetstest.moc"
+diff --git a/src/widgets/kdynamicjobtracker.cpp b/src/widgets/kdynamicjobtracker.cpp
+index 14924d5b..867489f6 100644
+--- a/src/widgets/kdynamicjobtracker.cpp
++++ b/src/widgets/kdynamicjobtracker.cpp
+@@ -25,6 +25,7 @@
+ #include <kjobtrackerinterface.h>
+ #include <kio/jobtracker.h>
+ 
++#include <QApplication>
+ #include <QDBusConnection>
+ #include <QDBusConnectionInterface>
+ #include <QDBusInterface>
+@@ -68,49 +69,77 @@ KDynamicJobTracker::~KDynamicJobTracker()
+ 
+ void KDynamicJobTracker::registerJob(KJob *job)
+ {
++    if (d->trackers.contains(job)) {
++        return;
++    }
++
++    // only interested in finished() signal,
++    // so catching ourselves instead of using KJobTrackerInterface::registerJob()
++    connect(job, &KJob::finished,
++            this, &KDynamicJobTracker::unregisterJob);
++
++    const bool canHaveWidgets = (qobject_cast<QApplication *>(qApp) != nullptr);
++
++    // always add an entry, even with no trackers used at all,
++    // so unregisterJob() will work as normal
++    AllTrackers& trackers = d->trackers[job];
++
+     // do not try to query kuiserver if dbus is not available
+     if (!QDBusConnection::sessionBus().interface()) {
+-        // fallback to widget tracker only!
+-        if (!d->widgetTracker) {
+-            d->widgetTracker = new KWidgetJobTracker();
++        if (canHaveWidgets) {
++            // fallback to widget tracker only!
++            if (!d->widgetTracker) {
++                d->widgetTracker = new KWidgetJobTracker();
++            }
++
++            trackers.widgetTracker = d->widgetTracker;
++            trackers.widgetTracker->registerJob(job);
++        } else {
++            trackers.widgetTracker = nullptr;
+         }
+-        d->trackers[job].widgetTracker = d->widgetTracker;
+-        d->trackers[job].widgetTracker->registerJob(job);
++
++        trackers.kuiserverTracker = nullptr;
+     } else {
+         if (!d->kuiserverTracker) {
+             d->kuiserverTracker = new KUiServerJobTracker();
+         }
+ 
+-        d->trackers[job].kuiserverTracker = d->kuiserverTracker;
+-        d->trackers[job].kuiserverTracker->registerJob(job);
+-
+-        QDBusInterface interface(QStringLiteral("org.kde.kuiserver"), QStringLiteral("/JobViewServer"), QLatin1String(""),
+-                                QDBusConnection::sessionBus(), this);
+-        QDBusReply<bool> reply = interface.call(QStringLiteral("requiresJobTracker"));
+-
+-        if (reply.isValid() && reply.value()) {
+-            //create a widget tracker in addition to kuiservertracker.
+-            if (!d->widgetTracker) {
+-                d->widgetTracker = new KWidgetJobTracker();
++        trackers.kuiserverTracker = d->kuiserverTracker;
++        trackers.kuiserverTracker->registerJob(job);
++
++        trackers.widgetTracker = nullptr;
++        if (canHaveWidgets) {
++            QDBusInterface interface(QStringLiteral("org.kde.kuiserver"), QStringLiteral("/JobViewServer"), QLatin1String(""),
++                                    QDBusConnection::sessionBus(), this);
++            QDBusReply<bool> reply = interface.call(QStringLiteral("requiresJobTracker"));
++
++            if (reply.isValid() && reply.value()) {
++                // create a widget tracker in addition to kuiservertracker.
++                if (!d->widgetTracker) {
++                    d->widgetTracker = new KWidgetJobTracker();
++                }
++                trackers.widgetTracker = d->widgetTracker;
++                trackers.widgetTracker->registerJob(job);
+             }
+-            d->trackers[job].widgetTracker = d->widgetTracker;
+-            d->trackers[job].widgetTracker->registerJob(job);
+         }
+     }
+-
+-    Q_ASSERT(d->trackers[job].kuiserverTracker || d->trackers[job].widgetTracker);
+ }
+ 
+ void KDynamicJobTracker::unregisterJob(KJob *job)
+ {
+-    KUiServerJobTracker *kuiserverTracker = d->trackers[job].kuiserverTracker;
+-    KWidgetJobTracker *widgetTracker = d->trackers[job].widgetTracker;
++    job->disconnect(this);
++
++    QMap<KJob*, AllTrackers>::Iterator it = d->trackers.find(job);
+ 
+-    if (!(widgetTracker || kuiserverTracker)) {
++    if (it == d->trackers.end()) {
+         qWarning() << "Tried to unregister a kio job that hasn't been registered.";
+         return;
+     }
+ 
++    const AllTrackers& trackers = it.value();
++    KUiServerJobTracker *kuiserverTracker = trackers.kuiserverTracker;
++    KWidgetJobTracker *widgetTracker = trackers.widgetTracker;
++
+     if (kuiserverTracker) {
+         kuiserverTracker->unregisterJob(job);
+     }
+@@ -118,6 +147,8 @@ void KDynamicJobTracker::unregisterJob(KJob *job)
+     if (widgetTracker) {
+         widgetTracker->unregisterJob(job);
+     }
++
++    d->trackers.erase(it);
+ }
+ 
+ Q_GLOBAL_STATIC(KDynamicJobTracker, globalJobTracker)
diff -Nru kio-5.28.0/debian/patches/Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch kio-5.28.0/debian/patches/Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch
--- kio-5.28.0/debian/patches/Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,59 @@
+From: Marco Scarpetta <marcoscarpetta02@gmail.com>
+Date: Wed, 1 Feb 2017 11:29:08 +0100
+Subject: Fix parsing of directories listing on a specific ftp server
+
+Directories listing on ftp servers like ftp://ftp-dee.poliba.it/ are now parsed correctly.
+
+BUG: 375610
+REVIEW: 129905
+FIXED-IN: 5.31
+---
+ src/ioslaves/ftp/ftp.cpp | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/src/ioslaves/ftp/ftp.cpp b/src/ioslaves/ftp/ftp.cpp
+index 2e129fcd..e41c7648 100644
+--- a/src/ioslaves/ftp/ftp.cpp
++++ b/src/ioslaves/ftp/ftp.cpp
+@@ -1669,24 +1669,35 @@ bool Ftp::ftpReadDir(FtpEntry &de)
+             }
+         }
+ 
++        // This is needed for ftp servers with a directory listing like this (#375610):
++        // drwxr-xr-x               folder        0 Mar 15 15:50 directory_name
++        if (strcmp(p_junk, "folder") == 0) {
++            p_date_1 = p_group;
++            p_date_2 = p_size;
++            p_size = p_owner;
++            p_group = nullptr;
++            p_owner = nullptr;
++        }
+         // Check whether the size we just read was really the size
+         // or a month (this happens when the server lists no group)
+         // Used to be the case on sunsite.uio.no, but not anymore
+         // This is needed for the Netware case, too.
+-        if (!isdigit(*p_size)) {
++        else if (!isdigit(*p_size)) {
+             p_date_1 = p_size;
++            p_date_2 = strtok(nullptr, " ");
+             p_size = p_group;
+             p_group = 0;
+             qCDebug(KIO_FTP) << "Size didn't have a digit -> size=" << p_size << " date_1=" << p_date_1;
+         } else {
+-            p_date_1 = strtok(NULL, " ");
++            p_date_1 = strtok(nullptr, " ");
++            p_date_2 = strtok(nullptr, " ");
+             qCDebug(KIO_FTP) << "Size has a digit -> ok. p_date_1=" << p_date_1;
+         }
+ 
+-        if (p_date_1 != 0 &&
+-                (p_date_2 = strtok(NULL, " ")) != 0 &&
+-                (p_date_3 = strtok(NULL, " ")) != 0 &&
+-                (p_name = strtok(NULL, "\r\n")) != 0) {
++        if (p_date_1 != nullptr &&
++                p_date_2 != nullptr &&
++                (p_date_3 = strtok(nullptr, " ")) != nullptr &&
++                (p_name = strtok(nullptr, "\r\n")) != nullptr) {
+             {
+                 QByteArray tmp(p_name);
+                 if (p_access[0] == 'l') {
diff -Nru kio-5.28.0/debian/patches/ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch kio-5.28.0/debian/patches/ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch
--- kio-5.28.0/debian/patches/ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,25 @@
+From: David Faure <faure@kde.org>
+Date: Sun, 1 Jan 2017 13:16:10 +0100
+Subject: ForwardingSlaveBase: fix passing of Overwrite flag to kio_desktop
+
+Unittest will be committed to plasma-workspace/kioslave/desktop later.
+
+BUG: 360487
+FIXED-IN: 5.30
+---
+ src/core/forwardingslavebase.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/forwardingslavebase.cpp b/src/core/forwardingslavebase.cpp
+index 5e724764..0a16c2ef 100644
+--- a/src/core/forwardingslavebase.cpp
++++ b/src/core/forwardingslavebase.cpp
+@@ -273,7 +273,7 @@ void ForwardingSlaveBase::symlink(const QString &target, const QUrl &dest,
+ 
+     QUrl new_dest;
+     if (d->internalRewriteUrl(dest, new_dest)) {
+-        KIO::SimpleJob *job = KIO::symlink(target, new_dest, flags & HideProgressInfo);
++        KIO::SimpleJob *job = KIO::symlink(target, new_dest, flags | HideProgressInfo);
+         d->connectSimpleJob(job);
+ 
+         d->eventLoop.exec();
diff -Nru kio-5.28.0/debian/patches/keep-query-encoding-when-HTTP-Proxy-is-used.patch kio-5.28.0/debian/patches/keep-query-encoding-when-HTTP-Proxy-is-used.patch
--- kio-5.28.0/debian/patches/keep-query-encoding-when-HTTP-Proxy-is-used.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/keep-query-encoding-when-HTTP-Proxy-is-used.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,24 @@
+From: Alexander Trufanov <trufanovan@gmail.com>
+Date: Tue, 21 Mar 2017 16:51:32 +0300
+Subject: keep query encoding when HTTP Proxy is used
+
+REVIEW:130040
+
+Otherwise some '%XX' parts of url query might be converted back to ASCII and this cause problems while passing info_hash to torrent trackers. Detailed description is in review.
+---
+ src/ioslaves/http/http.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/ioslaves/http/http.cpp b/src/ioslaves/http/http.cpp
+index 62eb09d2..0ea501d8 100644
+--- a/src/ioslaves/http/http.cpp
++++ b/src/ioslaves/http/http.cpp
+@@ -2322,7 +2322,7 @@ QString HTTPProtocol::formatRequestUri() const
+         u.setPort(m_request.url.port());
+         u.setPath(m_request.url.path(QUrl::FullyEncoded));
+         u.setQuery(m_request.url.query(QUrl::FullyEncoded));
+-        return u.toString();
++        return u.toString(QUrl::FullyEncoded);
+     } else {
+         QString result = m_request.url.path(QUrl::FullyEncoded);
+         if (m_request.url.hasQuery()) {
diff -Nru kio-5.28.0/debian/patches/kioexec-fix-support-for-suggestedfilename.patch kio-5.28.0/debian/patches/kioexec-fix-support-for-suggestedfilename.patch
--- kio-5.28.0/debian/patches/kioexec-fix-support-for-suggestedfilename.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/kioexec-fix-support-for-suggestedfilename.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,22 @@
+From: David Faure <faure@kde.org>
+Date: Mon, 3 Apr 2017 15:41:30 +0200
+Subject: kioexec: fix support for --suggestedfilename
+
+It was printing QCommandLineParser: option not defined: "suggestedfilename"
+---
+ src/kioexec/main.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/kioexec/main.cpp b/src/kioexec/main.cpp
+index d44893f5..a6199e81 100644
+--- a/src/kioexec/main.cpp
++++ b/src/kioexec/main.cpp
+@@ -273,7 +273,7 @@ int main(int argc, char **argv)
+     parser.addHelpOption();
+     parser.addVersionOption();
+     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("tempfiles") , i18n("Treat URLs as local files and delete them afterwards")));
+-    parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("suggestedfilename <file name>") , i18n("Suggested file name for the downloaded file")));
++    parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("suggestedfilename"), i18n("Suggested file name for the downloaded file"), "filename"));
+     parser.addPositionalArgument(QStringLiteral("command"), i18n("Command to execute"));
+     parser.addPositionalArgument(QStringLiteral("urls"), i18n("URL(s) or local file(s) used for 'command'"));
+ 
diff -Nru kio-5.28.0/debian/patches/kssl-Ensure-user-certificate-directory-has-been-created-b.patch kio-5.28.0/debian/patches/kssl-Ensure-user-certificate-directory-has-been-created-b.patch
--- kio-5.28.0/debian/patches/kssl-Ensure-user-certificate-directory-has-been-created-b.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/kssl-Ensure-user-certificate-directory-has-been-created-b.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,32 @@
+From: Michael Pyne <mpyne@kde.org>
+Date: Tue, 10 Jan 2017 21:05:48 -0500
+Subject: kssl: Ensure user certificate directory has been created before use.
+
+The KSSL KCM (in kdelibs4support) fails to save imported certificates to
+the user certificate store, unless the user store directory is manually
+created by the user first.  Fix by ensuring the directory is created
+before trying to save user certs.
+
+Differential Revision: https://phabricator.kde.org/D4060
+BUG: 342958
+FIXED-IN: 5.31
+---
+ src/core/ksslcertificatemanager.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/ksslcertificatemanager.cpp b/src/core/ksslcertificatemanager.cpp
+index 2c51cf7c..2e57e32f 100644
+--- a/src/core/ksslcertificatemanager.cpp
++++ b/src/core/ksslcertificatemanager.cpp
+@@ -247,9 +247,9 @@ bool KSslCertificateManagerPrivate::addCertificate(const KSslCaCertificate &in)
+     }
+ 
+     QString certFilename = userCertDir + QString::fromLatin1(in.certHash);
+-    //qDebug() << certFilename;
++
+     QFile certFile(certFilename);
+-    if (certFile.open(QIODevice::ReadOnly)) {
++    if (!QDir().mkpath(userCertDir) || certFile.open(QIODevice::ReadOnly)) {
+         return false;
+     }
+     if (!certFile.open(QIODevice::WriteOnly)) {
diff -Nru kio-5.28.0/debian/patches/kubuntu_kdelibs4-docs-path.diff kio-5.28.0/debian/patches/kubuntu_kdelibs4-docs-path.diff
--- kio-5.28.0/debian/patches/kubuntu_kdelibs4-docs-path.diff	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/kubuntu_kdelibs4-docs-path.diff	2017-04-05 10:10:59.000000000 +0200
@@ -10,7 +10,7 @@
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/src/ioslaves/help/kio_help.cpp b/src/ioslaves/help/kio_help.cpp
-index f555840..9a7b2fc 100644
+index f5558405..9a7b2fc9 100644
 --- a/src/ioslaves/help/kio_help.cpp
 +++ b/src/ioslaves/help/kio_help.cpp
 @@ -50,7 +50,8 @@ QString HelpProtocol::langLookup(const QString &fname)
diff -Nru kio-5.28.0/debian/patches/Never-stretch-the-last-date-column-in-the-file-dialog.patch kio-5.28.0/debian/patches/Never-stretch-the-last-date-column-in-the-file-dialog.patch
--- kio-5.28.0/debian/patches/Never-stretch-the-last-date-column-in-the-file-dialog.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Never-stretch-the-last-date-column-in-the-file-dialog.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,40 @@
+From: Andreas Hartmetz <ahartmetz@gmail.com>
+Date: Sat, 12 Nov 2016 18:42:08 +0100
+Subject: Never stretch the last (=date) column in the file dialog.
+
+Stretching the date column makes it appear to need the excessive
+width when adding up non-name column widths in expandNameColumn().
+The name column consequently became too narrow.
+Now why could the date column expand if the names needed a lot of
+space? It probably has something to do with expandNameColumn()
+being called several times while the directory model is loading
+and the exact order in which things are updated. Needs a more
+detailed analysis if this change causes a regression or still
+doesn't completely fix the problem.
+
+BUG: 312747
+---
+ src/filewidgets/kdiroperatordetailview.cpp | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/filewidgets/kdiroperatordetailview.cpp b/src/filewidgets/kdiroperatordetailview.cpp
+index 247f97c3..491aea57 100644
+--- a/src/filewidgets/kdiroperatordetailview.cpp
++++ b/src/filewidgets/kdiroperatordetailview.cpp
+@@ -91,7 +91,6 @@ bool KDirOperatorDetailView::setViewMode(KFile::FileView viewMode)
+     // using KDirOperator in horizontally limited parts of an app.
+     if (tree && m_hideDetailColumns) {
+         header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+-        header()->setStretchLastSection(false);
+     }
+ 
+     return true;
+@@ -102,7 +101,7 @@ bool KDirOperatorDetailView::event(QEvent *event)
+     if (event->type() == QEvent::Polish) {
+         QHeaderView *headerView = header();
+         headerView->setSectionResizeMode(QHeaderView::Interactive);
+-        headerView->setStretchLastSection(true);
++        headerView->setStretchLastSection(false);
+         headerView->setSectionsMovable(false);
+ 
+         setColumnHidden(KDirModel::Size, m_hideDetailColumns);
diff -Nru kio-5.28.0/debian/patches/report_error_removing_dirs kio-5.28.0/debian/patches/report_error_removing_dirs
--- kio-5.28.0/debian/patches/report_error_removing_dirs	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/report_error_removing_dirs	2017-04-05 10:10:59.000000000 +0200
@@ -8,7 +8,7 @@
  1 file changed, 13 insertions(+), 4 deletions(-)
 
 diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp
-index 12bf409..7dbafee 100644
+index 12bf4092..7dbafee4 100644
 --- a/src/core/copyjob.cpp
 +++ b/src/core/copyjob.cpp
 @@ -151,6 +151,7 @@ public:
diff -Nru kio-5.28.0/debian/patches/return_on_ACCESS_DENIED kio-5.28.0/debian/patches/return_on_ACCESS_DENIED
--- kio-5.28.0/debian/patches/return_on_ACCESS_DENIED	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/return_on_ACCESS_DENIED	2017-04-05 10:10:59.000000000 +0200
@@ -8,7 +8,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp
-index f2b67ce..d901a63 100644
+index f2b67ce5..d901a63d 100644
 --- a/src/ioslaves/file/file_unix.cpp
 +++ b/src/ioslaves/file/file_unix.cpp
 @@ -536,8 +536,8 @@ void FileProtocol::del(const QUrl &url, bool isfile)
diff -Nru kio-5.28.0/debian/patches/Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch kio-5.28.0/debian/patches/Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch
--- kio-5.28.0/debian/patches/Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch	1970-01-01 01:00:00.000000000 +0100
+++ kio-5.28.0/debian/patches/Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch	2017-04-05 10:10:59.000000000 +0200
@@ -0,0 +1,39 @@
+From: Albert Astals Cid <aacid@kde.org>
+Date: Tue, 28 Feb 2017 19:00:48 +0100
+Subject: Sanitize URLs before passing them to FindProxyForURL
+
+Remove user/password information
+For https: remove path and query
+
+Thanks to safebreach.com for reporting the problem
+
+CCMAIL: yoni.fridburg@safebreach.com
+CCMAIL: amit.klein@safebreach.com
+CCMAIL: itzik.kotler@safebreach.com
+---
+ src/kpac/script.cpp | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/src/kpac/script.cpp b/src/kpac/script.cpp
+index b009bc99..916f647a 100644
+--- a/src/kpac/script.cpp
++++ b/src/kpac/script.cpp
+@@ -754,9 +754,16 @@ QString Script::evaluate(const QUrl &url)
+         }
+     }
+ 
++    QUrl cleanUrl = url;
++    cleanUrl.setUserInfo(QString());
++    if (cleanUrl.scheme() == QLatin1String("https")) {
++        cleanUrl.setPath(QString());
++        cleanUrl.setQuery(QString());
++    }
++
+     QScriptValueList args;
+-    args << url.url();
+-    args << url.host();
++    args << cleanUrl.url();
++    args << cleanUrl.host();
+ 
+     QScriptValue result = func.call(QScriptValue(), args);
+     if (result.isError()) {
diff -Nru kio-5.28.0/debian/patches/series kio-5.28.0/debian/patches/series
--- kio-5.28.0/debian/patches/series	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/series	2017-04-05 10:10:59.000000000 +0200
@@ -4,3 +4,15 @@
 kubuntu_kdelibs4-docs-path.diff
 fix_kfreebsd_build
 fix_hurd_build.patch
+Never-stretch-the-last-date-column-in-the-file-dialog.patch
+Also-change-the-resize-mode-the-other-way.patch
+Allow-uppercase-checksums-matching-in-Checksums-tab.patch
+ForwardingSlaveBase-fix-passing-of-Overwrite-flag-to-kio_.patch
+Fix-another-clear-porting-bug-in-ForwardingSlaveBase.patch
+kssl-Ensure-user-certificate-directory-has-been-created-b.patch
+Fix-memleak-in-KDynamicJobTracker-KWidgetJobTracker-needs.patch
+Fix-parsing-of-directories-listing-on-a-specific-ftp-serv.patch
+Sanitize-URLs-before-passing-them-to-FindProxyForURL.patch
+keep-query-encoding-when-HTTP-Proxy-is-used.patch
+kioexec-fix-support-for-suggestedfilename.patch
+Fix-KDynamicJobTrackerTest-for-linkers-dropping-linked-li.patch
diff -Nru kio-5.28.0/debian/patches/wait_for_a_bit_longer kio-5.28.0/debian/patches/wait_for_a_bit_longer
--- kio-5.28.0/debian/patches/wait_for_a_bit_longer	2016-11-18 16:05:56.000000000 +0100
+++ kio-5.28.0/debian/patches/wait_for_a_bit_longer	2017-04-05 10:10:59.000000000 +0200
@@ -8,7 +8,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/autotests/kdirlistertest.cpp b/autotests/kdirlistertest.cpp
-index a91988f..e0a616b 100644
+index a91988f5..e0a616bf 100644
 --- a/autotests/kdirlistertest.cpp
 +++ b/autotests/kdirlistertest.cpp
 @@ -1186,7 +1186,7 @@ void KDirListerTest::testRemoveWatchedDirectory()

--- End Message ---
--- Begin Message ---
Maximiliano Curia:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@packages.debian.org
> Usertags: unblock
> 
> Dear release team,
> 
> I've backported some upstream fixes in kio for stretch that I consider 
> worthwhile, at least one of the changes fix the CVE-2017-6410 (#856889):
>  Sanitize URLs before passing them to FindProxyForURL (f9d0cb4)
> 
> [...]
> 
> I've uploaded 5.28.0-2 with these changes, and it has successfully built in 
> all the release architectures.
> 
> I'm attaching the corresponding debdiff.
> 
> Happy hacking,
> 
> Please unblock package kio
> 
> unblock kio/5.28.0-2
> 
> [...]

Unblocked, thanks.

~Niels

--- End Message ---

Reply to: