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++) +])
