diff options
author | B. Stack <bgstack15@gmail.com> | 2021-09-22 07:42:14 -0400 |
---|---|---|
committer | B. Stack <bgstack15@gmail.com> | 2021-09-22 07:42:14 -0400 |
commit | 48646da5bc2c571e808fa5c88f33f719d1f0a7d5 (patch) | |
tree | d31b12c7f4022c0efc232f6647efc94d4ebdfc54 | |
parent | Merge branch 'b11.13' into 'master' (diff) | |
download | FreeFileSync-48646da5bc2c571e808fa5c88f33f719d1f0a7d5.tar.gz FreeFileSync-48646da5bc2c571e808fa5c88f33f719d1f0a7d5.tar.bz2 FreeFileSync-48646da5bc2c571e808fa5c88f33f719d1f0a7d5.zip |
add upstream 11.14
-rw-r--r-- | Changelog.txt | 11 | ||||
-rw-r--r-- | FreeFileSync/Source/afs/native.cpp | 1 | ||||
-rw-r--r-- | FreeFileSync/Source/base/synchronization.cpp | 16 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/progress_indicator.cpp | 21 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/sync_cfg.cpp | 4 | ||||
-rw-r--r-- | FreeFileSync/Source/version/version.h | 2 | ||||
-rw-r--r-- | zen/open_ssl.cpp | 36 | ||||
-rw-r--r-- | zen/resolve_path.cpp | 11 | ||||
-rw-r--r-- | zen/resolve_path.h | 7 |
9 files changed, 60 insertions, 49 deletions
diff --git a/Changelog.txt b/Changelog.txt index 5b48fa6c..b6984b1d 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,4 +1,13 @@ -FreeFileSync 11.13 [2021-08-07] +FreeFileSync 11.14 [2021-09-20] +------------------------------- +Authenticate (S)FTP connections using OpenSSL 3.0 +Fixed E_NOINTERFACE error after synchronization +Preempt crashes due to Nahimic Sonic Studio 3 +Hide main window when minimizing progress window (macOS) +Avoid second dock icon when minimizing progress window (macOS) + + +FreeFileSync 11.13 [2021-08-17] ------------------------------- Manage default filter settings via GUI Support arbitrary location for local app installation (macOS) diff --git a/FreeFileSync/Source/afs/native.cpp b/FreeFileSync/Source/afs/native.cpp index e4285d66..2551234a 100644 --- a/FreeFileSync/Source/afs/native.cpp +++ b/FreeFileSync/Source/afs/native.cpp @@ -732,6 +732,7 @@ bool fff::acceptsItemPathPhraseNative(const Zstring& itemPathPhrase) //noexcept AbstractPath fff::createItemPathNative(const Zstring& itemPathPhrase) //noexcept { + warn_static("reevaluate") //TODO: get volume by name hangs for idle HDD! => run createItemPathNative during getFolderStatusNonBlocking() but getResolvedFilePath currently not thread-safe! const Zstring& itemPath = getResolvedFilePath(itemPathPhrase); return createItemPathNativeNoFormatting(itemPath); diff --git a/FreeFileSync/Source/base/synchronization.cpp b/FreeFileSync/Source/base/synchronization.cpp index 1a7aa58c..41a0eeab 100644 --- a/FreeFileSync/Source/base/synchronization.cpp +++ b/FreeFileSync/Source/base/synchronization.cpp @@ -256,15 +256,13 @@ void SyncStatistics::processFolder(const FolderPair& folder) } -/* - DeletionPolicy::permanent: deletion frees space - DeletionPolicy::recycler: won't free space until recycler is full, but then frees space - DeletionPolicy::versioning: depends on whether versioning folder is on a different volume --> if deleted item is a followed symlink, no space is freed --> created/updated/deleted item may be on a different volume than base directory: consider symlinks, junctions! - -=> generally assume deletion frees space; may avoid false-positive disk space warnings for recycler and versioning -*/ +/* DeletionPolicy::permanent: deletion frees space + DeletionPolicy::recycler: won't free space until recycler is full, but then frees space + DeletionPolicy::versioning: depends on whether versioning folder is on a different volume + -> if deleted item is a followed symlink, no space is freed + -> created/updated/deleted item may be on a different volume than base directory: consider symlinks, junctions! + + => generally assume deletion frees space; may avoid false-positive disk space warnings for recycler and versioning */ class MinimumDiskSpaceNeeded { public: diff --git a/FreeFileSync/Source/ui/progress_indicator.cpp b/FreeFileSync/Source/ui/progress_indicator.cpp index ad67effd..b772009d 100644 --- a/FreeFileSync/Source/ui/progress_indicator.cpp +++ b/FreeFileSync/Source/ui/progress_indicator.cpp @@ -1558,8 +1558,7 @@ void SyncProgressDialogImpl<TopLevelDialog>::onPause(wxCommandEvent& event) template <class TopLevelDialog> void SyncProgressDialogImpl<TopLevelDialog>::onIconize(wxIconizeEvent& event) { - /* - propagate progress dialog minimize/maximize to parent + /* propagate progress dialog minimize/maximize to parent ----------------------------------------------------- Fedora/Debian/Ubuntu: - wxDialog cannot be minimized @@ -1573,15 +1572,13 @@ void SyncProgressDialogImpl<TopLevelDialog>::onIconize(wxIconizeEvent& event) - probably the same issues with stray iconize events like Fedora/Debian/Ubuntu - minimize button is always shown, even if wxMINIMIZE_BOX is omitted! => nothing to do - Mac OS X: - - wxDialog can be minimized and automatically minimizes parent - - no iconize events seen by wxWidgets! - => nothing to do + macOS: + - wxDialog can be minimized but does not also minimize parent + => propagate event to parent Windows: - wxDialog can be minimized but does not also minimize parent - iconize events only seen for manual minimize - => propagate event to parent - */ + => propagate event to parent */ event.Skip(); } @@ -1651,10 +1648,14 @@ SyncProgressDialog* SyncProgressDialog::create(wxSize dlgSize, bool dlgMaximize, { if (parentWindow) //sync from GUI { - //due to usual "wxBugs", wxDialog on OS X does not float on its parent; wxFrame OTOH does => hack! - //https://groups.google.com/forum/#!topic/wx-users/J5SjjLaBOQE +#if 0 //macOS; update 08-2021: Bug seems to be fixed!? + //due to usual "wxBugs", wxDialog on OS X does not float on its parent; wxFrame OTOH does => hack! https://groups.google.com/forum/#!topic/wx-users/J5SjjLaBOQE + return new SyncProgressDialogImpl<wxFrame>(wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT, + dlgSize, dlgMaximize, userRequestAbort, syncStat, parentWindow, showProgress, autoCloseDialog, jobNames, syncStartTime, ignoreErrors, autoRetryCount, postSyncAction); +#else //GNOME bug: wxDialog seems to ignore wxMAXIMIZE_BOX | wxMINIMIZE_BOX! :( wxFrame OTOH has them, but adds an extra taskbar entry return new SyncProgressDialogImpl<wxDialog>(wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER, dlgSize, dlgMaximize, userRequestAbort, syncStat, parentWindow, showProgress, autoCloseDialog, jobNames, syncStartTime, ignoreErrors, autoRetryCount, postSyncAction); +#endif } else //FFS batch job { diff --git a/FreeFileSync/Source/ui/sync_cfg.cpp b/FreeFileSync/Source/ui/sync_cfg.cpp index d7e36f8e..81359450 100644 --- a/FreeFileSync/Source/ui/sync_cfg.cpp +++ b/FreeFileSync/Source/ui/sync_cfg.cpp @@ -46,7 +46,9 @@ void initBitmapRadioButtons(const std::vector<std::pair<ToggleButton*, std::stri auto generateSelectImage = [physicalLeft](wxButton& btn, const std::string& imgName, bool selected) { - wxImage imgTxt = createImageFromText(btn.GetLabel(), btn.GetFont(), btn.GetForegroundColour()); + wxImage imgTxt = createImageFromText(btn.GetLabel(), btn.GetFont(), + selected ? *wxBLACK : //accessibility: always set both foreground AND background colors! see renderSelectedButton() + btn.GetForegroundColour()); wxImage imgIco = mirrorIfRtl(loadImage(imgName, -1 /*maxWidth*/, getDefaultMenuIconSize())); diff --git a/FreeFileSync/Source/version/version.h b/FreeFileSync/Source/version/version.h index 692ce6bc..6c2e91e9 100644 --- a/FreeFileSync/Source/version/version.h +++ b/FreeFileSync/Source/version/version.h @@ -3,7 +3,7 @@ namespace fff { -const char ffsVersion[] = "11.13"; //internal linkage! +const char ffsVersion[] = "11.14"; //internal linkage! const char FFS_VERSION_SEPARATOR = '.'; } diff --git a/zen/open_ssl.cpp b/zen/open_ssl.cpp index 7c94263a..e875351c 100644 --- a/zen/open_ssl.cpp +++ b/zen/open_ssl.cpp @@ -179,9 +179,9 @@ std::shared_ptr<EVP_PKEY> streamToKey(const std::string& keyStream, RsaStreamTyp //================================================================================ -using EvpToBioFunc = int (*)(BIO* bio, EVP_PKEY* evp); +using EvpToBioFunc = int (*)(BIO* bio, const EVP_PKEY* evp); -std::string evpKeyToStream(EVP_PKEY* evp, EvpToBioFunc evpToBio, const char* functionName) //throw SysError +std::string evpKeyToStream(const EVP_PKEY* evp, EvpToBioFunc evpToBio, const char* functionName) //throw SysError { BIO* bio = ::BIO_new(BIO_s_mem()); if (!bio) @@ -205,16 +205,16 @@ std::string evpKeyToStream(EVP_PKEY* evp, EvpToBioFunc evpToBio, const char* fun } -using RsaToBioFunc = int (*)(BIO* bp, RSA* x); +using RsaToBioFunc = int (*)(BIO* bp, const RSA* x); -std::string evpKeyToStream(EVP_PKEY* evp, RsaToBioFunc rsaToBio, const char* functionName) //throw SysError +std::string evpKeyToStream(const EVP_PKEY* evp, RsaToBioFunc rsaToBio, const char* functionName) //throw SysError { BIO* bio = ::BIO_new(BIO_s_mem()); if (!bio) throw SysError(formatLastOpenSSLError("BIO_new")); ZEN_ON_SCOPE_EXIT(::BIO_free_all(bio)); - RSA* rsa = ::EVP_PKEY_get0_RSA(evp); //unowned reference! + const RSA* rsa = ::EVP_PKEY_get0_RSA(evp); //unowned reference! if (!rsa) throw SysError(formatLastOpenSSLError("EVP_PKEY_get0_RSA")); @@ -236,33 +236,33 @@ std::string evpKeyToStream(EVP_PKEY* evp, RsaToBioFunc rsaToBio, const char* fun //fix OpenSSL API inconsistencies: -int PEM_write_bio_PrivateKey2(BIO* bio, EVP_PKEY* key) +int PEM_write_bio_PrivateKey2(BIO* bio, const EVP_PKEY* key) { return ::PEM_write_bio_PrivateKey(bio, //BIO* bp - key, //EVP_PKEY* x + key, //const EVP_PKEY* x nullptr, //const EVP_CIPHER* enc - nullptr, //unsigned char* kstr + nullptr, //const unsigned char* kstr 0, //int klen nullptr, //pem_password_cb* cb nullptr); //void* u } -int PEM_write_bio_RSAPrivateKey2(BIO* bio, RSA* rsa) +int PEM_write_bio_RSAPrivateKey2(BIO* bio, const RSA* rsa) { return ::PEM_write_bio_RSAPrivateKey(bio, //BIO* bp - rsa, //RSA* x + rsa, //const RSA* x nullptr, //const EVP_CIPHER* enc - nullptr, //unsigned char* kstr + nullptr, //const unsigned char* kstr 0, //int klen nullptr, //pem_password_cb* cb nullptr); //void* u } -int PEM_write_bio_RSAPublicKey2(BIO* bio, RSA* rsa) { return ::PEM_write_bio_RSAPublicKey(bio, rsa); } +int PEM_write_bio_RSAPublicKey2(BIO* bio, const RSA* rsa) { return ::PEM_write_bio_RSAPublicKey(bio, rsa); } //-------------------------------------------------------------------------------- -std::string keyToStream(EVP_PKEY* evp, RsaStreamType streamType, bool publicKey) //throw SysError +std::string keyToStream(const EVP_PKEY* evp, RsaStreamType streamType, bool publicKey) //throw SysError { switch (streamType) { @@ -571,15 +571,15 @@ public: if (sslError == SSL_ERROR_ZERO_RETURN) return 0; //EOF + close_notify alert -#if OPENSSL_VERSION_NUMBER == 0x1010105fL //OpenSSL 1.1.1e +#if OPENSSL_VERSION_NUMBER >= 0x30000000L /*OpenSSL 3.0.0*/ || \ + OPENSSL_VERSION_NUMBER == 0x1010105fL /*OpenSSL 1.1.1e*/ const auto ec = ::ERR_peek_last_error(); if (sslError == SSL_ERROR_SSL && ERR_GET_REASON(ec) == SSL_R_UNEXPECTED_EOF_WHILE_READING) //EOF: only expected for HTTP/1.0 - return 0; -#else //obsolete handling, at least in OpenSSL 1.1.1e (but valid again with OpenSSL 1.1.1f!) - //https://github.com/openssl/openssl/issues/10880#issuecomment-575746226 +#else //obsolete handling: https://github.com/openssl/openssl/issues/10880#issuecomment-575746226 if ((sslError == SSL_ERROR_SYSCALL && ::ERR_peek_last_error() == 0)) //EOF: only expected for HTTP/1.0 - return 0; #endif + return 0; + throw SysError(formatLastOpenSSLError("SSL_read_ex") + L' ' + getSslErrorLiteral(sslError)); } assert(bytesReceived > 0); //SSL_read_ex() considers EOF an error! diff --git a/zen/resolve_path.cpp b/zen/resolve_path.cpp index 0e714528..4eab76ee 100644 --- a/zen/resolve_path.cpp +++ b/zen/resolve_path.cpp @@ -41,10 +41,14 @@ std::optional<Zstring> getEnvironmentVar(const Zstring& name) Zstring resolveRelativePath(const Zstring& relativePath) { - assert(runningOnMainThread()); //GetFullPathName() is documented to NOT be thread-safe! + assert(runningOnMainThread()); /* MSDN: "Multithreaded applications and shared library code should not use the GetFullPathName function - and should avoid using relative path names. - The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, */ + and should avoid using relative path names. The current directory state written by the + SetCurrentDirectory function is stored as a global variable in each process, + therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads, [...]" + + => Just plain wrong, there is no data corruption. What MSDN really means: GetFullPathName() is *perfectly* thread-safe, but depends + on the current directory, which is a process-scope global: https://devblogs.microsoft.com/oldnewthing/20210816-00/?p=105562 */ if (relativePath.empty()) return relativePath; @@ -268,7 +272,6 @@ Zstring zen::getResolvedFilePath(const Zstring& pathPhrase) //noexcept - \\?\-prefix requires absolute names - Volume Shadow Copy: volume name needs to be part of each file path - file icon buffer (at least for extensions that are actually read from disk, like "exe") - - Use of relative path names is not thread safe! (e.g. SHFileOperation) WINDOWS/LINUX: - detection of dependent directories, e.g. "\" and "C:\test" */ path = resolveRelativePath(path); diff --git a/zen/resolve_path.h b/zen/resolve_path.h index f2c427f1..4a5fc8fe 100644 --- a/zen/resolve_path.h +++ b/zen/resolve_path.h @@ -13,15 +13,12 @@ namespace zen { -/* - - expand macros +/* - expand macros - trim whitespace - expand volume path by name - convert relative paths into absolute - => may block for slow USB sticks and idle HDDs - => not thread-safe, see ::GetFullPathName()! -*/ + => may block for slow USB sticks and idle HDDs */ Zstring getResolvedFilePath(const Zstring& pathPhrase); //noexcept //macro substitution only |