Hello community,

here is the log from the commit of package libfilezilla for openSUSE:Factory 
checked in at 2020-10-25 18:07:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libfilezilla (Old)
 and      /work/SRC/openSUSE:Factory/.libfilezilla.new.3463 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libfilezilla"

Sun Oct 25 18:07:18 2020 rev:35 rq:843779 version:0.25.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libfilezilla/libfilezilla.changes        
2020-09-08 22:48:21.219546326 +0200
+++ /work/SRC/openSUSE:Factory/.libfilezilla.new.3463/libfilezilla.changes      
2020-10-25 18:07:24.543390090 +0100
@@ -1,0 +2,17 @@
+Wed Oct 21 10:37:04 UTC 2020 - ecsos <[email protected]>
+
+- Update to 0.25.0
+  * New features:
+    - Added fz::invoker to asynchronously call functions to run in
+      a specific thread independent of the caller's thread
+  * Bugfixes and minor changes:
+    - Added additional checks to fz::buffer to leave the buffer in
+      a valid state in out-of-memory situations and to prevent
+      mis-use
+    - Detect a particular socket buffer tuning issue under Linux
+      where setting a receiver buffer size shrinks the window scale
+      factor
+    - Reordered a few data members to reduce the amount of 
+      structure padding due to alignment
+
+-------------------------------------------------------------------

Old:
----
  libfilezilla-0.24.1.tar.bz2

New:
----
  libfilezilla-0.25.0.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libfilezilla.spec ++++++
--- /var/tmp/diff_new_pack.ToXx3j/_old  2020-10-25 18:07:25.059390578 +0100
+++ /var/tmp/diff_new_pack.ToXx3j/_new  2020-10-25 18:07:25.063390582 +0100
@@ -16,11 +16,11 @@
 #
 
 
-%define major          9
+%define major          10
 %define libname                %{name}%{major}
 %define develname      %{name}-devel
 Name:           libfilezilla
-Version:        0.24.1
+Version:        0.25.0
 Release:        0
 Summary:        C++ library for filezilla
 License:        GPL-2.0-or-later
@@ -32,12 +32,17 @@
 BuildRequires:  automake
 BuildRequires:  doxygen
 BuildRequires:  fdupes
+%if 0%{?suse_version} > 1500
 BuildRequires:  gcc-c++
+%else
+BuildRequires:  gcc8-c++
+%endif
 BuildRequires:  graphviz
 BuildRequires:  libtool
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(cppunit)
 BuildRequires:  pkgconfig(gnutls) >= 3.5.7
+BuildRequires:  pkgconfig(hogweed) >= 3.1
 BuildRequires:  pkgconfig(nettle) >= 3.1
 
 %description
@@ -90,6 +95,10 @@
 %patch0
 
 %build
+%if 0%{?suse_version} <= 1500
+export CC="%{_bindir}/gcc-8"
+export CXX="%{_bindir}/g++-8"
+%endif
 autoreconf -fi
 %configure --disable-static
 %make_build

++++++ libfilezilla-0.24.1.tar.bz2 -> libfilezilla-0.25.0.tar.bz2 ++++++
++++ 1669 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/NEWS new/libfilezilla-0.25.0/NEWS
--- old/libfilezilla-0.24.1/NEWS        2020-08-27 14:34:32.000000000 +0200
+++ new/libfilezilla-0.25.0/NEWS        2020-10-13 14:16:48.000000000 +0200
@@ -1,3 +1,10 @@
+0.25.0 (2020-10-13)
+
++ Added fz::invoker to asynchronously call functions to run in a specific 
thread independent of the caller's thread
+- Added additional checks to fz::buffer to leave the buffer in a valid state 
in out-of-memory situations and to prevent mis-use
+- Detect a particular socket buffer tuning issue under Linux where setting a 
receiver buffer size shrinks the window scale factor
+- Reordered a few data members to reduce the amount of structure padding due 
to alignment
+
 0.24.1 (2020-08-27)
 
 - fz::to_integral can now handle strongly typed enum return types
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/config/config.hpp.in 
new/libfilezilla-0.25.0/config/config.hpp.in
--- old/libfilezilla-0.24.1/config/config.hpp.in        2020-08-27 
14:34:39.000000000 +0200
+++ new/libfilezilla-0.25.0/config/config.hpp.in        2020-10-13 
14:17:40.000000000 +0200
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
+/* Define if TCP_INFO is supported */
+#undef HAVE_TCP_INFO
+
 /* Define to 1 if you have the `timegm' function. */
 #undef HAVE_TIMEGM
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/configure.ac new/libfilezilla-0.25.0/configure.ac
--- old/libfilezilla-0.24.1/configure.ac        2020-08-27 14:34:32.000000000 
+0200
+++ new/libfilezilla-0.25.0/configure.ac        2020-10-13 14:16:48.000000000 
+0200
@@ -1,4 +1,4 @@
-AC_INIT([libfilezilla],[0.24.1],[[email protected]],[],[https://lib.filezilla-project.org/])
+AC_INIT([libfilezilla],[0.25.0],[[email protected]],[],[https://lib.filezilla-project.org/])
 
 # Update the version information only immediately before a public release of 
your software
 # If the library source code has changed at all since the last update, then 
increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
@@ -6,7 +6,7 @@
 # If any interfaces have been added since the last public release, then 
increment age.
 # If any interfaces have been removed or changed since the last public 
release, then set age to 0.
 # CURRENT:REVISION:AGE
-LIBRARY_VERSION=9:1:0
+LIBRARY_VERSION=10:0:0
 
 
 AC_CONFIG_HEADERS([config/config.hpp])
@@ -117,6 +117,11 @@
   CHECK_ICONV([libdeps="$libdeps -liconv"])
 fi
 
+if test "$windows" = "0" && test "$mac" = "0"; then
+  CHECK_TCP_INFO
+fi
+
+
 AC_SUBST([libdeps])
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/Makefile.am new/libfilezilla-0.25.0/lib/Makefile.am
--- old/libfilezilla-0.24.1/lib/Makefile.am     2020-07-07 14:06:31.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/Makefile.am     2020-10-13 14:16:48.000000000 
+0200
@@ -9,6 +9,7 @@
        event_loop.cpp \
        file.cpp \
        hash.cpp \
+       invoker.cpp \
        iputils.cpp \
        local_filesys.cpp \
        mutex.cpp \
@@ -43,6 +44,7 @@
        libfilezilla/file.hpp \
        libfilezilla/format.hpp \
        libfilezilla/hash.hpp \
+       libfilezilla/invoker.hpp \
        libfilezilla/iputils.hpp \
        libfilezilla/libfilezilla.hpp \
        libfilezilla/local_filesys.hpp \
@@ -70,7 +72,8 @@
        libfilezilla/private/defs.hpp \
        libfilezilla/private/visibility.hpp \
        libfilezilla/private/windows.hpp \
-       libfilezilla/glue/wx.hpp
+       libfilezilla/glue/wx.hpp \
+       libfilezilla/glue/wxinvoker.hpp
 
 nobase_nodist_include_HEADERS = libfilezilla/version.hpp
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/buffer.cpp new/libfilezilla-0.25.0/lib/buffer.cpp
--- old/libfilezilla-0.24.1/lib/buffer.cpp      2020-07-07 14:06:31.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/buffer.cpp      2020-10-13 14:16:48.000000000 
+0200
@@ -30,6 +30,7 @@
        pos_ = buf.pos_;
        buf.pos_ = nullptr;
        size_ = buf.size_;
+       buf.size_ = 0;
        capacity_ = buf.capacity_;
        buf.capacity_ = 0;
 }
@@ -42,14 +43,18 @@
                        pos_ = data_;
                }
                else {
-                       capacity_ = std::max({ size_t(1024), capacity_ * 2, 
capacity_ + write_size });
-                       unsigned char* data = new unsigned char[capacity_];
+                       if (std::numeric_limits<size_t>::max() - capacity_ < 
write_size) {
+                               std::abort();
+                       }
+                       size_t const cap = std::max({ size_t(1024), capacity_ * 
2, capacity_ + write_size });
+                       unsigned char* d = new unsigned char[cap];
                        if (size_) {
-                               memcpy(data, pos_, size_);
+                               memcpy(d, pos_, size_);
                        }
                        delete[] data_;
-                       data_ = data;
-                       pos_ = data;
+                       capacity_ = cap;
+                       data_ = d;
+                       pos_ = d;
                }
        }
        return pos_ + size_;
@@ -58,14 +63,13 @@
 buffer& buffer::operator=(buffer const& buf)
 {
        if (this != &buf) {
-               delete[] data_;
+               unsigned char* d{};
                if (buf.size_) {
-                       data_ = new unsigned char[buf.capacity_];
-                       memcpy(data_, buf.pos_, buf.size_);
-               }
-               else {
-                       data_ = nullptr;
+                       d = new unsigned char[buf.capacity_];
+                       memcpy(d, buf.pos_, buf.size_);
                }
+               delete[] data_;
+               data_ = d;
                size_ = buf.size_;
                capacity_ = buf.capacity_;
                pos_ = data_;
@@ -83,6 +87,7 @@
                pos_ = buf.pos_;
                buf.pos_ = nullptr;
                size_ = buf.size_;
+               buf.size_ = 0;
                capacity_ = buf.capacity_;
                buf.capacity_ = 0;
        }
@@ -123,8 +128,34 @@
 
 void buffer::append(unsigned char const* data, size_t len)
 {
-       memcpy(get(len), data, len);
+       // Do the same initially as buffer::get would do, but don't delete the 
old pointer
+       // until after appending in case of append from own memory
+       unsigned char* old{};
+       if (capacity_ - (pos_ - data_) - size_ < len) {
+               if (capacity_ - size_ > len) {
+                       memmove(data_, pos_, size_);
+                       pos_ = data_;
+               }
+               else {
+                       if (std::numeric_limits<size_t>::max() - capacity_ < 
len) {
+                               std::abort();
+                       }
+                       size_t const cap = std::max({ size_t(1024), capacity_ * 
2, capacity_ + len });
+                       unsigned char* d = new unsigned char[cap];
+                       if (size_) {
+                               memcpy(d, pos_, size_);
+                       }
+                       old = data_;
+                       capacity_ = cap;
+                       data_ = d;
+                       pos_ = d;
+               }
+       }
+
+       memcpy(pos_ + size_, data, len);
        size_ += len;
+
+       delete [] old;
 }
 
 void buffer::append(std::string_view const& str)
@@ -134,17 +165,18 @@
 
 void buffer::reserve(size_t capacity)
 {
-       if (capacity_ > capacity) {
+       if (capacity_ >= capacity) {
                return;
        }
 
-       capacity_ = std::max(size_t(1024), capacity);
-       unsigned char* data = new unsigned char[capacity_];
+       size_t const cap = std::max(size_t(1024), capacity);
+       unsigned char* d = new unsigned char[cap];
        if (size_) {
-               memcpy(data, pos_, size_);
+               memcpy(d, pos_, size_);
        }
        delete[] data_;
-       data_ = data;
+       data_ = d;
+       capacity_ = cap;
        pos_ = data_;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/event_handler.cpp 
new/libfilezilla-0.25.0/lib/event_handler.cpp
--- old/libfilezilla-0.24.1/lib/event_handler.cpp       2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/event_handler.cpp       2020-10-13 
14:16:48.000000000 +0200
@@ -9,6 +9,11 @@
 {
 }
 
+event_handler::event_handler(event_handler const& h)
+       : event_loop_(h.event_loop_)
+{
+}
+
 event_handler::~event_handler()
 {
        assert(removing_); // To avoid races, the base class must have removed 
us already
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/event_loop.cpp 
new/libfilezilla-0.25.0/lib/event_loop.cpp
--- old/libfilezilla-0.24.1/lib/event_loop.cpp  2020-07-07 14:06:30.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/event_loop.cpp  2020-10-13 14:16:48.000000000 
+0200
@@ -4,7 +4,13 @@
 #include "libfilezilla/util.hpp"
 
 #include <algorithm>
-#include <cassert>
+
+#ifdef LFZ_EVENT_DEBUG
+#include <assert.h>
+#define event_assert(pred) assert((pred))
+#else
+#define event_assert(pred)
+#endif
 
 namespace fz {
 
@@ -33,6 +39,9 @@
 
 void event_loop::send_event(event_handler* handler, event_base* evt)
 {
+       event_assert(handler);
+       event_assert(evt);
+
        {
                scoped_lock lock(sync_);
                if (!handler->removing_) {
@@ -155,9 +164,9 @@
        ev = pending_events_.front();
        pending_events_.pop_front();
 
-       assert(ev.first);
-       assert(ev.second);
-       assert(!ev.first->removing_);
+       event_assert(ev.first);
+       event_assert(ev.second);
+       event_assert(!ev.first->removing_);
 
        active_handler_ = ev.first;
 
@@ -255,7 +264,7 @@
                }
 
                // Call event handler
-               assert(!handler->removing_);
+               event_assert(!handler->removing_);
 
                active_handler_ = handler;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/invoker.cpp new/libfilezilla-0.25.0/lib/invoker.cpp
--- old/libfilezilla-0.24.1/lib/invoker.cpp     1970-01-01 01:00:00.000000000 
+0100
+++ new/libfilezilla-0.25.0/lib/invoker.cpp     2020-10-13 14:16:48.000000000 
+0200
@@ -0,0 +1,35 @@
+#include "libfilezilla/invoker.hpp"
+
+#include <optional>
+
+namespace fz {
+thread_invoker::thread_invoker(event_loop& loop)
+       : event_handler(loop)
+{
+}
+
+thread_invoker::~thread_invoker()
+{
+       remove_handler();
+}
+
+void thread_invoker::operator()(fz::event_base const& ev)
+{
+       if (ev.derived_type() == invoker_event::type()) {
+               auto const& cb = std::get<0>(static_cast<invoker_event 
const&>(ev).v_);
+               if (cb) {
+                       cb();
+               }
+       }
+}
+
+invoker_factory get_invoker_factory(event_loop& loop)
+{
+       return [handler = std::optional<thread_invoker>(), 
&loop](std::function<void()> const& cb) mutable {
+               if (!handler) {
+                       handler.emplace(loop);
+               }
+               handler->send_event<invoker_event>(cb);
+       };
+}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/encode.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/encode.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/encode.hpp 2020-07-07 
14:06:30.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/encode.hpp 2020-10-13 
14:16:48.000000000 +0200
@@ -23,10 +23,10 @@
 template<typename Char>
 int hex_char_to_int(Char c)
 {
-       if (c >= 'a' && c <= 'z') {
+       if (c >= 'a' && c <= 'f') {
                return c - 'a' + 10;
        }
-       if (c >= 'A' && c <= 'Z') {
+       if (c >= 'A' && c <= 'F') {
                return c - 'A' + 10;
        }
        else if (c >= '0' && c <= '9') {
@@ -151,9 +151,9 @@
 std::string FZ_PUBLIC_SYMBOL base32_decode_s(std::wstring_view const& in, 
base32_type type = base32_type::standard);
 
 /**
- * \brief Percent-enodes string.
+ * \brief Percent-encodes string.
  *
- * The characters A-Z, a-z, 0-9, hyphen, underscore, period, tilde are not 
percent-encoded, optionally slashes arne't encoded either.
+ * The characters A-Z, a-z, 0-9, hyphen, underscore, period, tilde are not 
percent-encoded, optionally slashes aren't encoded either.
  * Every other character is encoded.
  *
  * \param keep_slashes If set, slashes are not encoded.
@@ -162,7 +162,7 @@
 std::string FZ_PUBLIC_SYMBOL percent_encode(std::wstring_view const& s, bool 
keep_slashes = false);
 
 /**
- * \brief Percent-encodes wide-character. Non-ASCII characters are converted 
to UTF-8 befor they are encoded.
+ * \brief Percent-encodes wide-character. Non-ASCII characters are converted 
to UTF-8 before they are encoded.
  *
  * \sa \ref fz::percent_encode
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/event.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/event.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/event.hpp  2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/event.hpp  2020-10-13 
14:16:48.000000000 +0200
@@ -52,7 +52,7 @@
 /**
 \brief This is the recommended event class.
 
-Instanciate the template with a unique type to identify the type of the event 
and a number of types for the values.
+Instantiate the template with a unique type to identify the type of the event 
and a number of types for the values.
 
 Keep the values simple, in particular avoid mutexes in your values.
 
@@ -90,7 +90,7 @@
                return type();
        }
 
-       /** \brief The event value, gets built from the arguments passed in the 
constructur.
+       /** \brief The event value, gets built from the arguments passed in the 
constructor.
         *
         * You don't need to access this member directly if you use the \ref 
dispatch mechanism.
         */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/event_handler.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/event_handler.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/event_handler.hpp  2020-07-07 
14:06:30.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/event_handler.hpp  2020-10-13 
14:16:48.000000000 +0200
@@ -59,7 +59,7 @@
        explicit event_handler(event_loop& loop);
        virtual ~event_handler();
 
-       event_handler(event_handler const&) = delete;
+       event_handler(event_handler const& h);
        event_handler& operator=(event_handler const&) = delete;
 
        /** \brief Deactivates handler, removes all pending events and stops 
all timers for this handler.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/event_loop.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/event_loop.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/event_loop.hpp     2020-07-07 
14:06:30.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/event_loop.hpp     2020-10-13 
14:16:48.000000000 +0200
@@ -111,8 +111,6 @@
        mutex sync_;
        condition cond_;
 
-       bool quit_{};
-
        event_handler * active_handler_{};
 
        monotonic_clock deadline_;
@@ -123,6 +121,8 @@
 
        std::unique_ptr<thread> thread_;
        std::unique_ptr<async_task> task_;
+
+       bool quit_{};
 };
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/format.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/format.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/format.hpp 2020-08-21 
15:35:14.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/format.hpp 2020-10-13 
14:16:48.000000000 +0200
@@ -362,7 +362,7 @@
        size_t arg_n{};
        while ((pos = fmt.find('%', start)) != InString::npos) {
 
-               // Copy segment preceeding the %
+               // Copy segment preceding the %
                ret += fmt.substr(start, pos - start);
 
                field f = detail::get_field(fmt, pos, arg_n, ret);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/glue/wx.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/glue/wx.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/glue/wx.hpp        2020-07-07 
14:06:30.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/glue/wx.hpp        2020-10-13 
14:16:48.000000000 +0200
@@ -1,6 +1,10 @@
 #ifndef LIBFILEZILLA_GLUE_WX_HEADER
 #define LIBFILEZILLA_GLUE_WX_HEADER
 
+/** \file
+ * \brief Glue to handle support wxString for some functions
+ */
+
 #include <wx/string.h>
 
 #include "../format.hpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/glue/wxinvoker.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/glue/wxinvoker.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/glue/wxinvoker.hpp 1970-01-01 
01:00:00.000000000 +0100
+++ new/libfilezilla-0.25.0/lib/libfilezilla/glue/wxinvoker.hpp 2020-10-13 
14:16:48.000000000 +0200
@@ -0,0 +1,43 @@
+#ifndef LIBFILEZILLA_GLUE_WXINVOKER_HEADER
+#define LIBFILEZILLA_GLUE_WXINVOKER_HEADER
+
+/** \file
+ * \brief Glue to create invokers using the event system of wxWidgets.
+ */
+
+#include "../invoker.hpp"
+
+#include <wx/event.h>
+
+namespace fz {
+
+/// \private
+template<typename... Args>
+std::function<void(Args...)> do_make_invoker(wxEvtHandler& handler, 
std::function<void(Args...)> && f)
+{
+       return [&handler, cf = f](Args&&... args) mutable {
+               auto cb = [cf, targs = 
std::make_tuple(std::forward<Args>(args)...)] {
+                       std::apply(cf, targs);
+               };
+               handler.CallAfter(cb);
+       };
+}
+
+/// \brief Alternative version of fz::invoke that accepts wxEvtHandler
+template<typename F>
+auto make_invoker(wxEvtHandler& handler, F && f)
+{
+       return do_make_invoker(handler, 
decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
+}
+
+/// \brief Returns an invoker factory utilizing the event system of of wx.
+inline invoker_factory get_invoker_factory(wxEvtHandler& handler)
+{
+       return [&handler](std::function<void()> const& cb) mutable {
+               handler.CallAfter(cb);
+       };
+}
+
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/hash.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/hash.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/hash.hpp   2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/hash.hpp   2020-10-13 
14:16:49.000000000 +0200
@@ -42,7 +42,7 @@
                update(&in, 1);
        }
 
-       /// Returns the raw digest and reinitalizes the accumulator
+       /// Returns the raw digest and reinitializes the accumulator
        std::vector<uint8_t> digest();
 
        operator std::vector<uint8_t>() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/invoker.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/invoker.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/invoker.hpp        1970-01-01 
01:00:00.000000000 +0100
+++ new/libfilezilla-0.25.0/lib/libfilezilla/invoker.hpp        2020-10-13 
14:16:49.000000000 +0200
@@ -0,0 +1,102 @@
+#ifndef LIBFILEZILLA_INVOKER_HEADER
+#define LIBFILEZILLA_INVOKER_HEADER
+
+/** \file
+ * \brief Declares fz::make_invoker and assorted machinery
+ */
+
+#include "event_handler.hpp"
+
+namespace fz {
+
+/// \private
+struct invoker_event_type{};
+
+/// \private
+typedef simple_event<invoker_event_type, std::function<void()>> invoker_event;
+
+/// \private
+class FZ_PUBLIC_SYMBOL thread_invoker final : public event_handler
+{
+public:
+       thread_invoker(event_loop& loop);
+       virtual ~thread_invoker();
+
+       virtual void operator()(event_base const& ev) override;
+};
+
+/// \private
+template<typename... Args>
+std::function<void(Args...)> do_make_invoker(event_loop& loop, 
std::function<void(Args...)> && f)
+{
+       return [handler = thread_invoker(loop), f](Args&&... args) mutable {
+               auto cb = [f, args = 
std::make_tuple(std::forward<Args>(args)...)] {
+                       std::apply(f, args);
+               };
+               handler.send_event<invoker_event>(std::move(cb));
+       };
+}
+
+// libc++ as shipped with Xcode does not have deduction guides for lambda -> 
std::function
+// Help it along a bit.
+/// \private
+template<typename Ret, typename F, typename ... Args>
+constexpr std::function<Ret(Args...)> get_func_type(Ret(F::*)(Args...) const);
+
+/**
+ * \brief Wraps the passed function, so that it is always invoked in the 
context of the loop.
+ *
+ * Returns a std::function with the same arguments as the passed function.
+ * The returned function can be called in any thread, as result the passed 
function is called
+ * asynchronously with the same arguments in the loop's thread.
+ */
+template<typename F>
+auto make_invoker(event_loop& loop, F && f)
+{
+       return do_make_invoker(loop, 
decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
+}
+template<typename F>
+auto make_invoker(event_handler& h, F && f)
+{
+       return do_make_invoker(h.event_loop_, 
decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
+}
+
+
+typedef std::function<void(std::function<void()>)> invoker_factory;
+
+/**
+ * \brief Creates an invoker factory.
+ *
+ * It is slower than building an invoker directly. Only use this
+ * if the abstraction is needed.
+ */
+invoker_factory FZ_PUBLIC_SYMBOL get_invoker_factory(event_loop& loop);
+
+/// \private
+template<typename... Args>
+std::function<void(Args...)> do_make_invoker(invoker_factory const& inv, 
std::function<void(Args...)> && f)
+{
+       return [inv, f](Args&&... args) mutable {
+               auto cb = [f, args = 
std::make_tuple(std::forward<Args>(args)...)] {
+                       std::apply(f, args);
+               };
+               inv(cb);
+       };
+}
+
+/**
+ * \brief Creates an invoker using the given factory
+ *
+ * Allows creating invokers independent of fz::event_loop,
+ * useful when interfacing with third-party event loops
+ * such as GUI frameworks, see also \ref glue/wxinvoker.hpp
+ */
+template<typename F>
+auto make_invoker(invoker_factory const& inv, F && f)
+{
+       return do_make_invoker(inv, 
decltype(get_func_type(&F::operator()))(std::forward<F>(f)));
+}
+
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/iputils.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/iputils.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/iputils.hpp        2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/iputils.hpp        2020-10-13 
14:16:49.000000000 +0200
@@ -11,7 +11,7 @@
 
 /** \brief Given a shortened IPv6 address, returns the full, unshortened 
address
  *
- * If passed address is encloded in square brackes, they are stripped.
+ * If passed address is encloded in square brackets, they are stripped.
  *
  * Returns an empty string if the passed string isn't a valid IPv6 address.
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/local_filesys.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/local_filesys.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/local_filesys.hpp  2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/local_filesys.hpp  2020-10-13 
14:16:49.000000000 +0200
@@ -126,17 +126,18 @@
        static native_string get_link_target(native_string const& path);
 
 private:
-       // State for directory enumeration
-       bool dirs_only_{};
 
 #ifdef FZ_WINDOWS
        WIN32_FIND_DATA m_find_data{};
        HANDLE m_hFind{INVALID_HANDLE_VALUE};
-       bool has_next_{};
        native_string m_find_path;
+       bool has_next_{};
 #else
        DIR* dir_{};
 #endif
+
+       // State for directory enumeration
+       bool dirs_only_{};
 };
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/logger.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/logger.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/logger.hpp 2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/logger.hpp 2020-10-13 
14:16:49.000000000 +0200
@@ -2,7 +2,7 @@
 #define LIBFILEZILLA_LOGGER_HEADER
 
 /** \file
- * Interface for logging
+ * \brief Interface for logging
  */
 
 #include "format.hpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/mutex.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/mutex.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/mutex.hpp  2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/mutex.hpp  2020-10-13 
14:16:49.000000000 +0200
@@ -19,8 +19,8 @@
  * \brief Lean replacement for std::(recursive_)mutex
  *
  * Unfortunately we can't use std::mutex and std::condition_variable as MinGW 
doesn't implement
- * C++11 threading yet. Even in those variants that at least mutexes and 
condition variables, they doen't
- * make use of Vista+'s CONDITION_VARIABLE, so it's too slow for our needs.
+ * C++11 threading yet. Even in those variants that at least have mutexes and 
condition variables,
+ * they don't make use of Vista+'s CONDITION_VARIABLE, so it's too slow for 
our needs.
  *
  * \note Once all platforms have C++11 threading implemented _in the fastest 
way possible_, this class will be removed.
  */
@@ -55,7 +55,7 @@
 
 /** \brief A simple scoped lock.
  *
- * The lock is aquired on construction and, if still locked, released on 
destruction.
+ * The lock is acquired on construction and, if still locked, released on 
destruction.
  * You can manually unlock and re-lock if needed.
  *
  * \note While this can be used with recursive mutexes, scoped_lock does not 
implement reference
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/optional.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/optional.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/optional.hpp       2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/optional.hpp       2020-10-13 
14:16:49.000000000 +0200
@@ -103,13 +103,12 @@
 sparse_optional<T>& sparse_optional<T>::operator=(sparse_optional<T> const& v)
 {
        if (this != &v) {
-               delete v_;
+               T* value{};
                if (v.v_) {
-                       v_ = new T(*v.v_);
-               }
-               else {
-                       v_ = nullptr;
+                       value = new T(*v.v_);
                }
+               delete v_;
+               v_ = value;
        }
 
        return *this;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/rate_limiter.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/rate_limiter.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/rate_limiter.hpp   2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/rate_limiter.hpp   2020-10-13 
14:16:49.000000000 +0200
@@ -4,7 +4,7 @@
 /** \file
  * \brief Classes for rate-limiting
  *
- * Rate-limiting is done using token buckets with hierachical limits.
+ * Rate-limiting is done using token buckets with hierarchical limits.
  * Rate is distributed fairly between buckets, with any overflow
  * distributed between buckets still having capacity.
  */
@@ -71,13 +71,12 @@
 
        void process(rate_limiter* limiter, bool locked);
 
+       std::atomic<int> activity_{2};
        mutex mtx_{false};
        std::vector<rate_limiter*> limiters_;
 
        std::atomic<timer_id> timer_{};
 
-       std::atomic<int> activity_{2};
-
        std::atomic<rate::type> burst_tolerance_{1};
 };
 
@@ -155,7 +154,7 @@
        virtual rate::type distribute_overflow(direction::type const /*d*/, 
rate::type /*tokens*/) { return 0; }
 
        /**
-        * \brief Recursively unlocks the mutexes of self and all childen.
+        * \brief Recursively unlocks the mutexes of self and all children.
         */
        virtual void unlock_tree() { mtx_.unlock(); }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/recursive_remove.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/recursive_remove.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/recursive_remove.hpp       
2020-07-07 14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/recursive_remove.hpp       
2020-10-13 14:16:49.000000000 +0200
@@ -35,7 +35,7 @@
        bool remove(std::list<native_string> dirsToVisit);
 
 protected:
-       /// \brief Can be overriden to ask the user for a confirmation.
+       /// \brief Can be overridden to ask the user for a confirmation.
        ///
        /// On Windows this isn't called, there SHFileOperation itself can ask 
for confirmation.
        /// See \ref adjust_shfileop
@@ -44,7 +44,7 @@
 #ifdef FZ_WINDOWS
        /// \brief Windows only: Allows customization of the SHFILEOPSTRUCT 
passed to SHFileOperation.
        ///
-       /// The default implementation allows undo and supresses any GUI output.
+       /// The default implementation allows undo and suppresses any GUI 
output.
        virtual void adjust_shfileop(SHFILEOPSTRUCT & op);
 #endif
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/rwmutex.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/rwmutex.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/rwmutex.hpp        2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/rwmutex.hpp        2020-10-13 
14:16:49.000000000 +0200
@@ -90,7 +90,7 @@
 
 /** \brief A simple scoped read lock.
  *
- * The lock is aquired on construction and, if still locked, released on 
destruction.
+ * The lock is acquired on construction and, if still locked, released on 
destruction.
  * You can manually unlock and re-lock if needed.
  *
  * There can be multiple readers.
@@ -182,7 +182,7 @@
 
 /** \brief A simple scoped read lock.
  *
- * The lock is aquired on construction and, if still locked, released on 
destruction.
+ * The lock is acquired on construction and, if still locked, released on 
destruction.
  * You can manually unlock and re-lock if needed.
  */
 class FZ_PUBLIC_SYMBOL scoped_write_lock final
@@ -234,7 +234,7 @@
 
        /** \brief Obtains the mutex.
         *
-        * Locking an alwritey locked scoped_write_lock results in undefined 
behavior.
+        * Locking an already locked scoped_write_lock results in undefined 
behavior.
         */
        void lock()
        {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/socket.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/socket.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/socket.hpp 2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/socket.hpp 2020-10-13 
14:16:49.000000000 +0200
@@ -199,17 +199,17 @@
        thread_pool & thread_pool_;
        event_handler* evt_handler_;
 
-       socket_t fd_{-1};
-
        socket_thread* socket_thread_{};
 
+       socket_event_source * const ev_source_{};
+
+       socket_t fd_{-1};
+
        unsigned int port_{};
 
        int family_;
 
        int buffer_sizes_[2];
-
-       socket_event_source * const ev_source_{};
 };
 
 class socket;
@@ -273,7 +273,7 @@
        /**
         * \brief Starts listening
         *
-        * If no port is given, let the operating system devcide on a port. Can 
use local_port to query it afterwards.
+        * If no port is given, let the operating system decide on a port. Can 
use local_port to query it afterwards.
         *
         * The address type, if not fz::address_type::unknown, must may the 
type of the address passed to bind()
         */
@@ -303,7 +303,7 @@
 
 
 /// State transitions are monotonically increasing
-enum class socket_state
+enum class socket_state : unsigned char
 {
        /// How the socket is initially
        none,
@@ -333,7 +333,7 @@
 /**
  * \brief Interface for sockets
  *
- * Can be used for layers, see fz::socket for the expexted semantics.
+ * Can be used for layers, see fz::socket for the expected semantics.
  */
 class FZ_PUBLIC_SYMBOL socket_interface : public socket_event_source
 {
@@ -359,7 +359,7 @@
         * Only disallows further sends, does not affect reading from the
         * socket.
         *
-        * Returns 0 on success, an erorr code otherwise.
+        * Returns 0 on success, an error code otherwise.
         * If it returns EGAIN, shutdown is not yet complete. Call shutdown
         * again after the next write event.
         */
@@ -517,10 +517,10 @@
        friend class listen_socket;
        native_string host_;
 
-       socket_state state_{};
+       duration keepalive_interval_;
 
        int flags_{};
-       duration keepalive_interval_;
+       socket_state state_{};
 };
 
 /**
@@ -551,16 +551,16 @@
        virtual void set_event_handler(event_handler* handler) override;
 
        /**
-        * Can be overriden to return something different, e.g. a proxy layer
+        * Can be overridden to return something different, e.g. a proxy layer
         * would return the hostname of the peer connected to through the proxy,
-        * whereas the next layer would return the address of the proxy istself.
+        * whereas the next layer would return the address of the proxy itself.
         */
        virtual native_string peer_host() const override { return 
next_layer_.peer_host(); }
 
        /**
-        * Can be overriden to return something different, e.g. a proxy layer
+        * Can be overridden to return something different, e.g. a proxy layer
         * would return the post of the peer connected to through the proxy,
-        * whereas the next layer would return the port of the proxy istself.
+        * whereas the next layer would return the port of the proxy itself.
         */
        virtual int peer_port(int& error) const override { return 
next_layer_.peer_port(error); }
 
@@ -575,7 +575,7 @@
         *
         * \return 0 on success
         * \return EAGAIN if the shutdown cannot be completed, wait for a read 
event and try again.
-        * \return otherwise an error has occured.
+        * \return otherwise an error has occurred.
         *
         * On an ordinary socket, this is a no-op. Some layers however may 
return an EOF before the
         * next lower layer has reached its own EOF, such as the EOF of the 
secure channel from
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/string.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/string.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/string.hpp 2020-08-27 
14:34:32.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/string.hpp 2020-10-13 
14:16:48.000000000 +0200
@@ -114,9 +114,9 @@
 std::string FZ_PUBLIC_SYMBOL str_toupper_ascii(std::string_view const& s);
 std::wstring FZ_PUBLIC_SYMBOL str_toupper_ascii(std::wstring_view const& s);
 
-/** \brief Comparator to be used for std::map for case-insentitive keys
+/** \brief Comparator to be used for std::map for case-insensitive keys
  *
- * Comparision is done locale-agnostic.
+ * Comparison is done locale-agnostic.
  * Useful for key-value pairs in protocols, e.g. HTTP headers.
  */
 struct FZ_PUBLIC_SYMBOL less_insensitive_ascii final
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/time.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/time.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/time.hpp   2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/time.hpp   2020-10-13 
14:16:49.000000000 +0200
@@ -32,7 +32,7 @@
 
 The internal representation of \c datetime is in milliseconds since 1970-01-01 
00:00:00.000 UTC and can handle a
 range of several million years. While datetime supports negative times (i.e. 
earlier than 1970-01-01 00:00:00.000 UTC),
-the underlying plaform may not support it.
+the underlying platform may not support it.
 
 \remark Some *nix systems base their time on TAI instead of UTC, though we 
pretend there
 is no difference, as the latter is the default on every modern distribution.
@@ -131,7 +131,7 @@
 
        /** \name Adding/subtracting duration intervals
         *
-        * Adding or subracting a \ref duration interval is accuracy-aware, 
e.g. adding a single second to a datetime with
+        * Adding or subtracting a \ref duration interval is accuracy-aware, 
e.g. adding a single second to a datetime with
         * minute-accuracy does not change the timestamp.
         */
        datetime& operator+=(duration const& op);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/tls_layer.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/tls_layer.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/tls_layer.hpp      2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/tls_layer.hpp      2020-10-13 
14:16:48.000000000 +0200
@@ -61,13 +61,13 @@
         *
         * If the handshake is started, wait for a connection event for the 
result.
         *
-        * If no verification handler is passed, verification is done soley 
using the system
+        * If no verification handler is passed, verification is done solely 
using the system
         * trust store.
         *
         * If a verification handler is passed, it will receive a
         * \ref certificate_verification_event event upon which the handshake 
is paused until
         * \ref set_verification_result gets called including a \ref 
tls_session_info structure.
-        * The handler is called even for certifates not trusted by the system 
trust store, allowing
+        * The handler is called even for certificates not trusted by the 
system trust store, allowing
         * the following impairments: Unknown issuer, wrong hostname and 
certificates used outside their validity time.
         */
        bool client_handshake(event_handler *const verification_handler, 
std::vector<uint8_t> const& session_to_resume = std::vector<uint8_t>(), 
native_string const& session_hostname = native_string());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/libfilezilla/uri.hpp 
new/libfilezilla-0.25.0/lib/libfilezilla/uri.hpp
--- old/libfilezilla-0.24.1/lib/libfilezilla/uri.hpp    2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/libfilezilla/uri.hpp    2020-10-13 
14:16:49.000000000 +0200
@@ -51,7 +51,7 @@
        bool empty() const;
        explicit operator bool() const { return !empty(); }
 
-       /// Often refered to as the protocol prefix, e.g. ftp://
+       /// Often referred to as the protocol prefix, e.g. ftp://
        std::string scheme_;
 
        /// Optional user part of the authority
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/local_filesys.cpp 
new/libfilezilla-0.25.0/lib/local_filesys.cpp
--- old/libfilezilla-0.24.1/lib/local_filesys.cpp       2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/local_filesys.cpp       2020-10-13 
14:16:48.000000000 +0200
@@ -133,7 +133,7 @@
 #ifndef FZ_WINDOWS
 local_filesys::type get_file_info_impl(int(*do_stat)(struct stat & buf, char 
const* path, DIR* dir, bool follow), char const* path, DIR* dir, bool &is_link, 
int64_t* size, datetime* modification_time, int *mode, bool follow_links)
 {
-       struct stat buf;
+       struct stat buf{};
        static_assert(sizeof(buf.st_size) >= 8, "The st_size member of struct 
stat must be 8 bytes or larger.");
 
        int result = do_stat(buf, path, dir, false);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/process.cpp new/libfilezilla-0.25.0/lib/process.cpp
--- old/libfilezilla-0.24.1/lib/process.cpp     2020-07-07 14:06:31.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/process.cpp     2020-10-13 14:16:49.000000000 
+0200
@@ -324,8 +324,7 @@
 
 void make_arg(native_string const& arg, 
std::vector<std::unique_ptr<native_string::value_type[]>> & argList)
 {
-       std::unique_ptr<char[]> ret;
-       ret.reset(new char[arg.size() + 1]);
+       auto ret = std::make_unique<char[]>(arg.size() + 1);
        memcpy(ret.get(), arg.c_str(), arg.size() + 1);
        argList.push_back(std::move(ret));
 }
@@ -338,7 +337,7 @@
                make_arg(*it, argList);
        }
 
-       argV.reset(new char *[argList.size() + 1]);
+       argV = std::make_unique<char*[]>(argList.size() + 1);
        char ** v = argV.get();
        for (auto const& a : argList) {
                *(v++) = a.get();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/socket.cpp new/libfilezilla-0.25.0/lib/socket.cpp
--- old/libfilezilla-0.24.1/lib/socket.cpp      2020-08-21 15:35:14.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/socket.cpp      2020-10-13 14:16:48.000000000 
+0200
@@ -32,6 +32,9 @@
   #if HAVE_EVENTFD
        #include <sys/eventfd.h>
   #endif
+  #if HAVE_TCP_INFO
+       #include <atomic>
+  #endif
 #endif
 
 #include <assert.h>
@@ -65,6 +68,26 @@
        sockaddr_in in4;
        sockaddr_in6 in6;
 };
+
+#if HAVE_TCP_INFO
+// Attempting to set a high SND_RCVBUF can actually result in a smaller
+// TCP receive window scale factor.
+// Through TCP_INFO it is possible to detect this, and if it is the case,
+// avoid setting TCP_RCVBUF
+std::atomic<int> unmodified_rcv_wscale{};
+std::atomic<int> modified_rcv_wscale{};
+
+int get_rcv_wscale(int fd) {
+       tcp_info i{};
+       socklen_t len = sizeof(tcp_info);
+       int res = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &i, &len);
+       if (res) {
+               return 0;
+       }
+       return i.tcpi_rcv_wscale;
+}
+
+#endif
 }
 
 void remove_socket_events(event_handler * handler, socket_event_source const* 
const source)
@@ -280,14 +303,21 @@
 int do_set_buffer_sizes(socket::socket_t fd, int size_read, int size_write)
 {
        int ret = 0;
-       if (size_read != -1) {
-               int res = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const 
char*)&size_read, sizeof(size_read));
-               if (res != 0) {
-                       ret = last_socket_error();
+       if (size_read >= 0) {
+#if HAVE_TCP_INFO
+               // Check if setting the buffer size shrinks the window scale 
factor
+               int const mws = modified_rcv_wscale;
+               if (!mws || mws >= unmodified_rcv_wscale)
+#endif
+               {
+                       int res = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const 
char*)&size_read, sizeof(size_read));
+                       if (res != 0) {
+                               ret = last_socket_error();
+                       }
                }
        }
 
-       if (size_write != -1) {
+       if (size_write >= 0) {
                int res = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const 
char*)&size_write, sizeof(size_write));
                if (res != 0) {
                        ret = last_socket_error();
@@ -622,6 +652,15 @@
                else {
                        static_cast<socket*>(socket_)->state_ = 
socket_state::connected;
 
+#if HAVE_TCP_INFO
+                       if (socket_->buffer_sizes_[0] == -1 && 
!unmodified_rcv_wscale) {
+                               unmodified_rcv_wscale = 
get_rcv_wscale(socket_->fd_);
+                       }
+                       else if (socket_->buffer_sizes_[0] != -1 && 
!modified_rcv_wscale) {
+                               modified_rcv_wscale = 
get_rcv_wscale(socket_->fd_);
+                       }
+#endif
+
                        if (socket_->evt_handler_) {
                                
socket_->evt_handler_->send_event<socket_event>(socket_->ev_source_, 
socket_event_flag::connection, 0);
                        }
@@ -1097,6 +1136,11 @@
        std::string port_;
        std::string bind_;
 
+       mutex mutex_;
+       condition condition_;
+
+       async_task thread_;
+
 #ifdef FZ_WINDOWS
        // We wait on this using WSAWaitForMultipleEvents
        WSAEVENT sync_event_{WSA_INVALID_EVENT};
@@ -1107,11 +1151,6 @@
        int pipe_[2]{-1, -1};
 #endif
 
-       mutex mutex_;
-       condition condition_;
-
-       bool quit_{};
-
        // The socket events we are waiting for
        int waiting_{};
 
@@ -1119,10 +1158,10 @@
        int triggered_{};
        int triggered_errors_[WAIT_EVENTCOUNT];
 
+       bool quit_{};
+
        // Thread waits for instructions
        bool threadwait_{};
-
-       async_task thread_;
 };
 
 socket_base::socket_base(thread_pool& pool, event_handler* evt_handler, 
socket_event_source* ev_source)
@@ -1340,7 +1379,19 @@
 
        scoped_lock l(socket_thread_->mutex_);
 
-       buffer_sizes_[0] = size_receive;
+#if HAVE_TCP_INFO
+       // Explicitly ignore setting buffer size until after the unmodified 
window scale factor is known.
+       if (unmodified_rcv_wscale)
+#endif
+       {
+               if (size_receive < 0) {
+                       // Remember if we ever changd it
+                       buffer_sizes_[0] = (buffer_sizes_[0] == -1) ? -1 : -2;
+               }
+               else {
+                       buffer_sizes_[0] = size_receive;
+               }
+       }
        buffer_sizes_[1] = size_send;
 
        if (fd_ == -1) {
@@ -1678,8 +1729,8 @@
 
 #if !defined(SO_NOSIGPIPE) && !defined(FZ_WINDOWS)
        // Some systems have neither. Need to block signal
-       sigaction old_action;
-       sigaction action = {};
+       struct sigaction old_action;
+       struct sigaction action = {};
        action.sa_handler = SIG_IGN;
        int signal_set = sigaction(SIGPIPE, &action, &old_action);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/string.cpp new/libfilezilla-0.25.0/lib/string.cpp
--- old/libfilezilla-0.24.1/lib/string.cpp      2020-07-07 14:06:31.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/string.cpp      2020-10-13 14:16:49.000000000 
+0200
@@ -8,6 +8,7 @@
 #include <iconv.h>
 #include <strings.h>
 
+#include <memory>
 #include <type_traits>
 #endif
 
@@ -306,18 +307,16 @@
                if (holder && iconv(holder.cd, nullptr, nullptr, nullptr, 
nullptr) != static_cast<size_t>(-1)) {
                        auto in_p = const_cast<iconv_second_arg_type>(s);
                        size_t out_len = len * sizeof(wchar_t) * 2;
-                       char* out_buf = new char[out_len];
-                       char* out_p = out_buf;
+                       auto out_buf = std::make_unique<char[]>(out_len);
+                       char* out_p = out_buf.get();
 
                        size_t r = iconv(holder.cd, &in_p, &len, &out_p, 
&out_len);
 
                        if (r != static_cast<size_t>(-1)) {
-                               ret.assign(reinterpret_cast<wchar_t*>(out_buf), 
reinterpret_cast<wchar_t*>(out_p));
+                               
ret.assign(reinterpret_cast<wchar_t*>(out_buf.get()), 
reinterpret_cast<wchar_t*>(out_p));
                        }
 
                        // Our buffer should big enough as well, so we can 
ignore errors such as E2BIG.
-
-                       delete [] out_buf;
                }
 #endif
        }
@@ -411,18 +410,16 @@
                        size_t in_len = in.size() * sizeof(wchar_t);
 
                        size_t out_len = in.size() * 4;
-                       char* out_buf = new char[out_len];
-                       char* out_p = out_buf;
+                       auto out_buf = std::make_unique<char[]>(out_len);
+                       char* out_p = out_buf.get();
 
                        size_t r = iconv(holder.cd, &in_p, &in_len, &out_p, 
&out_len);
 
                        if (r != static_cast<size_t>(-1)) {
-                               ret.assign(out_buf, out_p);
+                               ret.assign(out_buf.get(), out_p);
                        }
 
                        // Our buffer should big enough as well, so we can 
ignore errors such as E2BIG.
-
-                       delete[] out_buf;
                }
 #endif
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/thread_pool.cpp 
new/libfilezilla-0.25.0/lib/thread_pool.cpp
--- old/libfilezilla-0.24.1/lib/thread_pool.cpp 2020-07-07 14:06:31.000000000 
+0200
+++ new/libfilezilla-0.25.0/lib/thread_pool.cpp 2020-10-13 14:16:48.000000000 
+0200
@@ -62,10 +62,11 @@
        mutex & m_;
        condition thread_cond_;
 
-       bool task_waiting_{};
        condition task_cond_;
 
        thread_pool& pool_;
+
+       bool task_waiting_{};
 private:
        bool quit_{};
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/lib/tls_layer_impl.hpp 
new/libfilezilla-0.25.0/lib/tls_layer_impl.hpp
--- old/libfilezilla-0.24.1/lib/tls_layer_impl.hpp      2020-07-07 
14:06:31.000000000 +0200
+++ new/libfilezilla-0.25.0/lib/tls_layer_impl.hpp      2020-10-13 
14:16:48.000000000 +0200
@@ -114,17 +114,16 @@
 
        tls_layer& tls_layer_;
 
-       socket_state state_{};
-
        logger_interface & logger_;
 
-       bool initialized_{};
-
        gnutls_session_t session_{};
 
        std::vector<uint8_t> ticket_key_;
 
        gnutls_certificate_credentials_t cert_credentials_{};
+
+       socket_state state_{};
+
        bool handshake_successful_{};
        bool sent_closure_alert_{};
 
@@ -142,9 +141,6 @@
 
        std::vector<uint8_t> required_certificate_;
 
-       bool socket_eof_{};
-       int socket_error_{}; // Set in the push and pull functions if 
reading/writing fails fatally
-
        friend class tls_layer;
        friend class tls_layerCallbacks;
 
@@ -153,6 +149,11 @@
        tls_system_trust_store* system_trust_store_{};
 
        event_handler * verification_handler_{};
+
+       int socket_error_{}; // Set in the push and pull functions if 
reading/writing fails fatally
+       bool socket_eof_{};
+
+       bool initialized_{};
 };
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/libfilezilla-0.24.1/m4/check_tcp_info.m4 
new/libfilezilla-0.25.0/m4/check_tcp_info.m4
--- old/libfilezilla-0.24.1/m4/check_tcp_info.m4        1970-01-01 
01:00:00.000000000 +0100
+++ new/libfilezilla-0.25.0/m4/check_tcp_info.m4        2020-10-13 
14:16:49.000000000 +0200
@@ -0,0 +1,32 @@
+dnl Checks for thread_local support
+
+AC_DEFUN([CHECK_TCP_INFO], [
+
+  AC_MSG_CHECKING([for TCP_INFO])
+
+  AC_LANG_PUSH(C++)
+
+  AC_COMPILE_IFELSE([
+    AC_LANG_PROGRAM([[
+      #include <sys/types.h>
+      #include <sys/socket.h>
+      #include <netinet/in.h>
+      #include <netinet/tcp.h>
+    ]], [[
+      tcp_info info{};
+      int fd{};
+      socklen_t len = sizeof(tcp_info);
+      int res = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &len);
+      (void)res;
+      (void)info.tcpi_rcv_wscale;
+      return 0;
+    ]])
+  ], [
+    AC_MSG_RESULT([yes])
+    AC_DEFINE([HAVE_TCP_INFO], [1], [Define if TCP_INFO is supported])
+  ], [
+    AC_MSG_RESULT([no])
+  ])
+
+  AC_LANG_POP(C++)
+])


Reply via email to