diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2020-03-20 22:40:40 +0000 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2020-03-20 22:40:40 +0000 |
commit | 7a3869712e5c23b8e5e17ece4cbbf3d5909de5a6 (patch) | |
tree | a43b1c04f9947fe02d7d5444354f0176c28ed594 | |
parent | Merge branch '10.21' into 'master' (diff) | |
parent | add upstream 10.22 (diff) | |
download | FreeFileSync-10.22.tar.gz FreeFileSync-10.22.tar.bz2 FreeFileSync-10.22.zip |
Merge branch '10.22' into 'master'10.22
add upstream 10.22
See merge request opensource-tracking/FreeFileSync!19
-rwxr-xr-x | Changelog.txt | 5 | ||||
-rw-r--r-- | FreeFileSync/Source/afs/ftp.cpp | 22 | ||||
-rw-r--r-- | FreeFileSync/Source/afs/gdrive.cpp | 18 | ||||
-rw-r--r-- | FreeFileSync/Source/application.cpp | 5 | ||||
-rw-r--r-- | FreeFileSync/Source/base/db_file.cpp | 2 | ||||
-rw-r--r-- | FreeFileSync/Source/fatal_error.h | 2 | ||||
-rw-r--r-- | FreeFileSync/Source/log_file.cpp | 2 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/abstract_folder_picker.cpp | 2 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/folder_pair.h | 8 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/log_panel.cpp | 6 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/main_dlg.cpp | 12 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/progress_indicator.cpp | 12 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/small_dlgs.cpp | 6 | ||||
-rw-r--r-- | FreeFileSync/Source/ui/sync_cfg.cpp | 4 | ||||
-rw-r--r-- | FreeFileSync/Source/version/version.h | 2 | ||||
-rw-r--r-- | zen/format_unit.cpp | 2 | ||||
-rw-r--r-- | zen/open_ssl.cpp | 17 | ||||
-rw-r--r-- | zen/string_base.h | 7 | ||||
-rw-r--r-- | zen/zstring.cpp | 2 |
19 files changed, 74 insertions, 62 deletions
diff --git a/Changelog.txt b/Changelog.txt index cc6a1c8a..8717bc73 100755 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,8 @@ +FreeFileSync 10.22 [2020-03-18] +------------------------------- +Fixed upper-case conversion bug for non-ASCII strings + + FreeFileSync 10.21 [2020-03-17] ------------------------------- Preselect last-used email address diff --git a/FreeFileSync/Source/afs/ftp.cpp b/FreeFileSync/Source/afs/ftp.cpp index 394c5966..795692db 100644 --- a/FreeFileSync/Source/afs/ftp.cpp +++ b/FreeFileSync/Source/afs/ftp.cpp @@ -102,9 +102,9 @@ Zstring ansiToUtfEncoding(const std::string& str) //throw SysError if (!utfStr) { if (!error) - throw SysError(L"g_convert: unknown error. (" + utfTo<std::wstring>(str) + L")"); //user should never see this + throw SysError(L"g_convert: unknown error. (" + utfTo<std::wstring>(str) + L')'); //user should never see this - throw SysError(formatSystemError(L"g_convert(" + utfTo<std::wstring>(str) + L")", + throw SysError(formatSystemError(L"g_convert(" + utfTo<std::wstring>(str) + L')', replaceCpy(_("Error Code %x"), L"%x", numberTo<std::wstring>(error->code)), utfTo<std::wstring>(error->message)) ); } ZEN_ON_SCOPE_EXIT(::g_free(utfStr)); @@ -132,9 +132,9 @@ std::string utfToAnsiEncoding(const Zstring& str) //throw SysError if (!ansiStr) { if (!error) - throw SysError(L"g_convert: unknown error. (" + utfTo<std::wstring>(str) + L")"); //user should never see this + throw SysError(L"g_convert: unknown error. (" + utfTo<std::wstring>(str) + L')'); //user should never see this - throw SysError(formatSystemError(L"g_convert(" + utfTo<std::wstring>(str) + L")", + throw SysError(formatSystemError(L"g_convert(" + utfTo<std::wstring>(str) + L')', replaceCpy(_("Error Code %x"), L"%x", numberTo<std::wstring>(error->code)), utfTo<std::wstring>(error->message))); } ZEN_ON_SCOPE_EXIT(::g_free(ansiStr)); @@ -1020,7 +1020,7 @@ private: ++itBegin; auto itBlank = std::find(itBegin, rawLine.end(), ' '); if (itBlank == rawLine.end()) - throw SysError(L"Item name not available. (" + utfTo<std::wstring>(rawLine) + L")"); + throw SysError(L"Item name not available. (" + utfTo<std::wstring>(rawLine) + L')'); const std::string facts(itBegin, itBlank); item.itemName = serverToUtfEncoding(std::string(itBlank + 1, rawLine.end()), enc); //throw SysError @@ -1043,7 +1043,7 @@ private: const TimeComp tc = parseTime("%Y%m%d%H%M%S", modifyFact); if (tc == TimeComp()) - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(modifyFact) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(modifyFact) + L')'); item.modTime = utcToTimeT(tc); //returns -1 on error if (item.modTime == -1) @@ -1052,7 +1052,7 @@ private: tc.year == 1601) // => is this also relevant in this context of MLST UTC time?? item.modTime = 0; else - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(modifyFact) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(modifyFact) + L')'); } } @@ -1070,12 +1070,12 @@ private: //evaluate parsing errors right now (+ report raw entry in error message!) if (item.itemName.empty()) - throw SysError(L"Item name not available. (" + utfTo<std::wstring>(rawLine) + L")"); + throw SysError(L"Item name not available. (" + utfTo<std::wstring>(rawLine) + L')'); if (item.type == AFS::ItemType::FILE) { if (!fileSize) - throw SysError(L"File size not available. (" + utfTo<std::wstring>(rawLine) + L")"); + throw SysError(L"File size not available. (" + utfTo<std::wstring>(rawLine) + L')'); item.fileSize = *fileSize; } @@ -1288,7 +1288,7 @@ private: } catch (const SysError& e) { - throw SysError(L"Failed to parse FTP response. (" + utfTo<std::wstring>(rawLine) + L")" + (haveGroup ? L"" : L" [no-group]") + L' ' + e.toString()); + throw SysError(L"Failed to parse FTP response. (" + utfTo<std::wstring>(rawLine) + L')' + (haveGroup ? L"" : L" [no-group]") + L' ' + e.toString()); } } @@ -1771,7 +1771,7 @@ private: { const std::string isoTime = utfTo<std::string>(formatTime(Zstr("%Y%m%d%H%M%S"), getUtcTime(*modTime_))); //returns empty string on failure if (isoTime.empty()) - throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime_) + L")"); + throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime_) + L')'); accessFtpSession(login_, [&](FtpSession& session) //throw SysError { diff --git a/FreeFileSync/Source/afs/gdrive.cpp b/FreeFileSync/Source/afs/gdrive.cpp index 467c40fe..d653a030 100644 --- a/FreeFileSync/Source/afs/gdrive.cpp +++ b/FreeFileSync/Source/afs/gdrive.cpp @@ -474,7 +474,7 @@ GoogleAccessInfo authorizeAccessToGoogleDrive(const Zstring& googleLoginHint, co if (addr.ss_family != AF_INET && addr.ss_family != AF_INET6) - throw SysError(L"getsockname: unknown protocol family (" + numberTo<std::wstring>(addr.ss_family) + L")"); + throw SysError(L"getsockname: unknown protocol family (" + numberTo<std::wstring>(addr.ss_family) + L')'); const int port = ntohs(reinterpret_cast<const sockaddr_in&>(addr).sin_port); //the socket is not bound to a specific local IP => inet_ntoa(reinterpret_cast<const sockaddr_in&>(addr).sin_addr) == "0.0.0.0" @@ -781,7 +781,7 @@ std::vector<GoogleFileItem> readFolderContent(const std::string& folderId, const //RFC 3339 date-time: e.g. "2018-09-29T08:39:12.053Z" const TimeComp tc = parseTime("%Y-%m-%dT%H:%M:%S", beforeLast(*modifiedTime, '.', IF_MISSING_RETURN_ALL)); if (tc == TimeComp() || !endsWith(*modifiedTime, 'Z')) //'Z' means "UTC" => it seems Google doesn't use the time-zone offset postfix - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L')'); time_t modTime = utcToTimeT(tc); //returns -1 on error if (modTime == -1) @@ -790,7 +790,7 @@ std::vector<GoogleFileItem> readFolderContent(const std::string& folderId, const tc.year == 1601) // => yes, possible even on Google Drive: https://freefilesync.org/forum/viewtopic.php?t=6602 modTime = 0; else - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L')'); } std::vector<std::string> parentIds; @@ -892,7 +892,7 @@ ChangesDelta getChangesDelta(const std::string& startPageToken, const std::strin //RFC 3339 date-time: e.g. "2018-09-29T08:39:12.053Z" const TimeComp tc = parseTime("%Y-%m-%dT%H:%M:%S", beforeLast(*modifiedTime, '.', IF_MISSING_RETURN_ALL)); if (tc == TimeComp() || !endsWith(*modifiedTime, 'Z')) //'Z' means "UTC" => it seems Google doesn't use the time-zone offset postfix - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L')'); itemDetails.modTime = utcToTimeT(tc); //returns -1 on error if (itemDetails.modTime == -1) @@ -901,7 +901,7 @@ ChangesDelta getChangesDelta(const std::string& startPageToken, const std::strin tc.year == 1601) // => yes, possible even on Google Drive: https://freefilesync.org/forum/viewtopic.php?t=6602 itemDetails.modTime = 0; else - throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L")"); + throw SysError(L"Modification time could not be parsed. (" + utfTo<std::wstring>(*modifiedTime) + L')'); } for (const auto& parentVal : parents->arrayVal) @@ -1060,7 +1060,7 @@ void gdriveMoveAndRenameItem(const std::string& itemId, const std::string& paren //RFC 3339 date-time: e.g. "2018-09-29T08:39:12.053Z" const std::string modTimeRfc = utfTo<std::string>(formatTime(Zstr("%Y-%m-%dT%H:%M:%S.000Z"), getUtcTime(newModTime))); //returns empty string on failure if (modTimeRfc.empty()) - throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(newModTime) + L")"); + throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(newModTime) + L')'); const std::string& postBuf = std::string("{\n") + "\"name\": \"" + utfTo<std::string>(newName) + "\",\n" + @@ -1096,7 +1096,7 @@ void setModTime(const std::string& itemId, time_t modTime, const std::string& ac //RFC 3339 date-time: e.g. "2018-09-29T08:39:12.053Z" const std::string& modTimeRfc = formatTime<std::string>("%Y-%m-%dT%H:%M:%S.000Z", getUtcTime(modTime)); //returns empty string on failure if (modTimeRfc.empty()) - throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(modTime) + L")"); + throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(modTime) + L')'); const std::string postBuf = R"({ "modifiedTime": ")" + modTimeRfc + "\" }"; @@ -1152,7 +1152,7 @@ std::string /*itemId*/ gdriveUploadSmallFile(const Zstring& fileName, const std: { const std::string& modTimeRfc = formatTime<std::string>("%Y-%m-%dT%H:%M:%S.000Z", getUtcTime(*modTime)); //returns empty string on failure if (modTimeRfc.empty()) - throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime) + L")"); + throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime) + L')'); metaDataBuf += "\"modifiedTime\": \"" + modTimeRfc + "\",\n"; } @@ -1252,7 +1252,7 @@ std::string /*itemId*/ gdriveUploadFile(const Zstring& fileName, const std::stri { const std::string& modTimeRfc = utfTo<std::string>(formatTime(Zstr("%Y-%m-%dT%H:%M:%S.000Z"), getUtcTime(*modTime))); //returns empty string on failure if (modTimeRfc.empty()) - throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime) + L")"); + throw SysError(L"Invalid modification time (time_t: " + numberTo<std::wstring>(*modTime) + L')'); postBuf += "\"modifiedTime\": \"" + modTimeRfc + "\",\n"; } diff --git a/FreeFileSync/Source/application.cpp b/FreeFileSync/Source/application.cpp index 65755b0e..bc78b74e 100644 --- a/FreeFileSync/Source/application.cpp +++ b/FreeFileSync/Source/application.cpp @@ -479,8 +479,7 @@ void showSyntaxHelp() L" [" + _("config files:") + L" *.ffs_gui/*.ffs_batch]" + L'\n' + L" [-DirPair " + _("directory") + L' ' + _("directory") + L"]" L"\n" + L" [-Edit]" + L'\n' + - L" [" + _("global config file:") + L" GlobalSettings.xml]" + L"\n" - L"\n" + + L" [" + _("global config file:") + L" GlobalSettings.xml]" + L"\n\n" + _("config files:") + L'\n' + _("Any number of FreeFileSync \"ffs_gui\" and/or \"ffs_batch\" configuration files.") + L"\n\n" + @@ -488,7 +487,7 @@ void showSyntaxHelp() L"-DirPair " + _("directory") + L' ' + _("directory") + L'\n' + _("Any number of alternative directory pairs for at most one config file.") + L"\n\n" + - L"-Edit" + "\n" + + L"-Edit" + '\n' + _("Open the selected configuration for editing only, without executing it.") + L"\n\n" + _("global config file:") + L'\n' + diff --git a/FreeFileSync/Source/base/db_file.cpp b/FreeFileSync/Source/base/db_file.cpp index 23e42776..b1f187d0 100644 --- a/FreeFileSync/Source/base/db_file.cpp +++ b/FreeFileSync/Source/base/db_file.cpp @@ -725,7 +725,7 @@ struct StreamStatusNotifier void operator()(int64_t bytesDelta) //throw ThreadInterruption { bytesTotal_ += bytesDelta; - acb_.updateStatus(msgPrefix_ + L" (" + formatFilesizeShort(bytesTotal_) + L")"); //throw ThreadInterruption + acb_.updateStatus(msgPrefix_ + L" (" + formatFilesizeShort(bytesTotal_) + L')'); //throw ThreadInterruption } private: diff --git a/FreeFileSync/Source/fatal_error.h b/FreeFileSync/Source/fatal_error.h index 84ceb6dc..476a8075 100644 --- a/FreeFileSync/Source/fatal_error.h +++ b/FreeFileSync/Source/fatal_error.h @@ -33,7 +33,7 @@ void logFatalError(const std::string& msg) //noexcept using namespace zen; assert(false); //this is stuff we like to debug - const std::string logEntry = '[' + utfTo<std::string>(formatTime(formatDateTag) + Zstr(' ') + formatTime(formatTimeTag)) + "] " + msg; + const std::string logEntry = '[' + utfTo<std::string>(formatTime(formatDateTimeTag)) + "] " + msg; try { saveBinContainer(getConfigDirPathPf() + Zstr("LastError.log"), logEntry, nullptr /*notifyUnbufferedIO*/); //throw FileError diff --git a/FreeFileSync/Source/log_file.cpp b/FreeFileSync/Source/log_file.cpp index b7032137..c89d4403 100644 --- a/FreeFileSync/Source/log_file.cpp +++ b/FreeFileSync/Source/log_file.cpp @@ -419,7 +419,7 @@ void saveNewLogFile(const AbstractPath& logFilePath, //throw FileError, X (int64_t bytesDelta) mutable { if (notifyStatus) - notifyStatus(msg_ + L" (" + formatFilesizeShort(bytesWritten_ += bytesDelta) + L")"); //throw X + notifyStatus(msg_ + L" (" + formatFilesizeShort(bytesWritten_ += bytesDelta) + L')'); //throw X }; std::unique_ptr<AFS::OutputStream> logFileStream = AFS::getOutputStream(logFilePath, std::nullopt /*streamSize*/, std::nullopt /*modTime*/, notifyUnbufferedIO); //throw FileError diff --git a/FreeFileSync/Source/ui/abstract_folder_picker.cpp b/FreeFileSync/Source/ui/abstract_folder_picker.cpp index 8f2fe782..1380faec 100644 --- a/FreeFileSync/Source/ui/abstract_folder_picker.cpp +++ b/FreeFileSync/Source/ui/abstract_folder_picker.cpp @@ -195,7 +195,7 @@ void AbstractFolderPickerDlg::populateNodeThen(const wxTreeItemId& itemId, const itemData->loadStatus = NodeLoadStatus::loading; - m_treeCtrlFileSystem->SetItemText(itemId, getNodeDisplayName(itemData->folderPath) + L" (" + _("Loading...") + L")"); + m_treeCtrlFileSystem->SetItemText(itemId, getNodeDisplayName(itemData->folderPath) + L" (" + _("Loading...") + L')'); guiQueue_.processAsync([folderPath = itemData->folderPath] //AbstractPath is thread-safe like an int! { diff --git a/FreeFileSync/Source/ui/folder_pair.h b/FreeFileSync/Source/ui/folder_pair.h index c3ee65bb..dbcb386f 100644 --- a/FreeFileSync/Source/ui/folder_pair.h +++ b/FreeFileSync/Source/ui/folder_pair.h @@ -59,18 +59,18 @@ private: setImage(*basicPanel_.m_bpButtonLocalCompCfg, greyScaleIfDisabled(imgCmp_, !!localCmpCfg_)); basicPanel_.m_bpButtonLocalCompCfg->SetToolTip(localCmpCfg_ ? - _("Local comparison settings") + L" (" + getVariantName(localCmpCfg_->compareVar) + L")" : + _("Local comparison settings") + L" (" + getVariantName(localCmpCfg_->compareVar) + L')' : _("Local comparison settings")); setImage(*basicPanel_.m_bpButtonLocalSyncCfg, greyScaleIfDisabled(imgSync_, !!localSyncCfg_)); basicPanel_.m_bpButtonLocalSyncCfg->SetToolTip(localSyncCfg_ ? - _("Local synchronization settings") + L" (" + getVariantName(localSyncCfg_->directionCfg.var) + L")" : + _("Local synchronization settings") + L" (" + getVariantName(localSyncCfg_->directionCfg.var) + L')' : _("Local synchronization settings")); setImage(*basicPanel_.m_bpButtonLocalFilter, greyScaleIfDisabled(imgFilter_, !isNullFilter(localFilter_))); basicPanel_.m_bpButtonLocalFilter->SetToolTip(!isNullFilter(localFilter_) ? - _("Local filter") + L" (" + _("Active") + L")" : - _("Local filter") + L" (" + _("None") + L")"); + _("Local filter") + L" (" + _("Active") + L')' : + _("Local filter") + L" (" + _("None") + L')'); } void OnLocalCompCfgContext(wxCommandEvent& event) diff --git a/FreeFileSync/Source/ui/log_panel.cpp b/FreeFileSync/Source/ui/log_panel.cpp index 52322dc9..fbd895b8 100644 --- a/FreeFileSync/Source/ui/log_panel.cpp +++ b/FreeFileSync/Source/ui/log_panel.cpp @@ -360,9 +360,9 @@ void LogPanel::setLog(const std::shared_ptr<const ErrorLog>& log) btn.SetToolTip(tooltip); }; - initButton(*m_bpButtonErrors, L"msg_error", _("Error" ) + L" (" + formatNumber(logCount.error + logCount.fatal) + L")"); - initButton(*m_bpButtonWarnings, L"msg_warning", _("Warning") + L" (" + formatNumber(logCount.warning ) + L")"); - initButton(*m_bpButtonInfo, L"msg_info", _("Info" ) + L" (" + formatNumber(logCount.info ) + L")"); + initButton(*m_bpButtonErrors, L"msg_error", _("Error" ) + L" (" + formatNumber(logCount.error + logCount.fatal) + L')'); + initButton(*m_bpButtonWarnings, L"msg_warning", _("Warning") + L" (" + formatNumber(logCount.warning ) + L')'); + initButton(*m_bpButtonInfo, L"msg_info", _("Info" ) + L" (" + formatNumber(logCount.info ) + L')'); m_bpButtonErrors ->setActive(true); m_bpButtonWarnings->setActive(true); diff --git a/FreeFileSync/Source/ui/main_dlg.cpp b/FreeFileSync/Source/ui/main_dlg.cpp index 4dcad8b3..77c4c1c9 100644 --- a/FreeFileSync/Source/ui/main_dlg.cpp +++ b/FreeFileSync/Source/ui/main_dlg.cpp @@ -3367,7 +3367,7 @@ void MainDialog::onCfgGridContext(GridClickEvent& event) } submenu.addItem(name, applyBackColor, &bmpSquare, !selectedRows.empty()); }; - addColorOption(wxNullColour, L"(" + _("&Default") + L")"); //meta options should be enclosed in parentheses + addColorOption(wxNullColour, L'(' + _("&Default") + L')'); //meta options should be enclosed in parentheses addColorOption({ 0xff, 0xd8, 0xcb }, _("Red")); addColorOption({ 0xff, 0xf9, 0x99 }, _("Yellow")); addColorOption({ 0xcc, 0xff, 0x99 }, _("Green")); @@ -3815,7 +3815,7 @@ void MainDialog::updateGlobalFilterButton() setImage(*m_bpButtonFilter, greyScaleIfDisabled(getResourceImage(L"cfg_filter"), !isNullFilter(currentCfg_.mainCfg.globalFilter))); const std::wstring status = !isNullFilter(currentCfg_.mainCfg.globalFilter) ? _("Active") : _("None"); - m_bpButtonFilter->SetToolTip(_("Filter") + L" (F7) (" + status + L")"); + m_bpButtonFilter->SetToolTip(_("Filter") + L" (F7) (" + status + L')'); m_bpButtonFilterContext->SetToolTip(m_bpButtonFilter->GetToolTipText()); } @@ -4356,7 +4356,7 @@ void MainDialog::setLastOperationLog(const ProcessSummary& summary, const std::s m_staticTextItemsProcessed->SetLabel(formatNumber(summary.statsProcessed.items)); - m_staticTextBytesProcessed->SetLabel(L"(" + formatFilesizeShort(summary.statsProcessed.bytes) + L")"); + m_staticTextBytesProcessed->SetLabel(L'(' + formatFilesizeShort(summary.statsProcessed.bytes) + L')'); const bool hideRemainingStats = (summary.statsTotal.items < 0 && summary.statsTotal.bytes < 0) || //no total items/bytes: e.g. for pure folder comparison summary.statsProcessed == summary.statsTotal; //...if everything was processed successfully @@ -4369,7 +4369,7 @@ void MainDialog::setLastOperationLog(const ProcessSummary& summary, const std::s if (!hideRemainingStats) { m_staticTextItemsRemaining->SetLabel( formatNumber(summary.statsTotal.items - summary.statsProcessed.items)); - m_staticTextBytesRemaining->SetLabel(L"(" + formatFilesizeShort(summary.statsTotal.bytes - summary.statsProcessed.bytes) + L")"); + m_staticTextBytesRemaining->SetLabel(L'(' + formatFilesizeShort(summary.statsTotal.bytes - summary.statsProcessed.bytes) + L')'); } const int64_t totalTimeSec = std::chrono::duration_cast<std::chrono::seconds>(summary.totalTime).count(); @@ -4807,14 +4807,14 @@ void MainDialog::setStatusBarFileStats(FileView::FileStats statsLeft, setText(*m_staticTextStatusLeftDirs, _P("1 directory", "%x directories", statsLeft.folderCount)); setText(*m_staticTextStatusLeftFiles, _P("1 file", "%x files", statsLeft.fileCount)); - setText(*m_staticTextStatusLeftBytes, L"(" + formatFilesizeShort(statsLeft.bytes) + L")"); + setText(*m_staticTextStatusLeftBytes, L'(' + formatFilesizeShort(statsLeft.bytes) + L')'); //------------------------------------------------------------------------------ bSizerStatusRightDirectories->Show(statsRight.folderCount > 0); bSizerStatusRightFiles ->Show(statsRight.fileCount > 0); setText(*m_staticTextStatusRightDirs, _P("1 directory", "%x directories", statsRight.folderCount)); setText(*m_staticTextStatusRightFiles, _P("1 file", "%x files", statsRight.fileCount)); - setText(*m_staticTextStatusRightBytes, L"(" + formatFilesizeShort(statsRight.bytes) + L")"); + setText(*m_staticTextStatusRightBytes, L'(' + formatFilesizeShort(statsRight.bytes) + L')'); //------------------------------------------------------------------------------ wxString statusCenterNew; if (filegrid::getDataView(*m_gridMainC).rowsTotal() > 0) diff --git a/FreeFileSync/Source/ui/progress_indicator.cpp b/FreeFileSync/Source/ui/progress_indicator.cpp index 04c20716..7e1ee3d9 100644 --- a/FreeFileSync/Source/ui/progress_indicator.cpp +++ b/FreeFileSync/Source/ui/progress_indicator.cpp @@ -226,7 +226,7 @@ void CompareProgressPanel::Impl::init(const Statistics& syncStat, bool ignoreErr stopWatch_.restart(); //measure total time - setText(*m_staticTextRetryCount, std::wstring(L"(") + formatNumber(automaticRetryCount) + MULT_SIGN + L")"); + setText(*m_staticTextRetryCount, L'(' + formatNumber(automaticRetryCount) + MULT_SIGN + L')'); bSizerErrorsRetry->Show(automaticRetryCount > 0); //allow changing a few options dynamically during sync @@ -341,10 +341,10 @@ void CompareProgressPanel::Impl::updateProgressGui() else { setText(*m_staticTextItemsProcessed, formatNumber(itemsCurrent), &layoutChanged); - setText(*m_staticTextBytesProcessed, L"(" + formatFilesizeShort(bytesCurrent) + L")", &layoutChanged); + setText(*m_staticTextBytesProcessed, L'(' + formatFilesizeShort(bytesCurrent) + L')', &layoutChanged); setText(*m_staticTextItemsRemaining, formatNumber(itemsTotal - itemsCurrent), &layoutChanged); - setText(*m_staticTextBytesRemaining, L"(" + formatFilesizeShort(bytesTotal - bytesCurrent) + L")", &layoutChanged); + setText(*m_staticTextBytesRemaining, L'(' + formatFilesizeShort(bytesTotal - bytesCurrent) + L')', &layoutChanged); } //current time elapsed @@ -880,7 +880,7 @@ syncStat_(&syncStat) pnl_.bSizerDynSpace->SetMinSize(yLabelWidth, -1); //ensure item/time stats are nicely centered - setText(*pnl_.m_staticTextRetryCount, std::wstring(L"(") + formatNumber(automaticRetryCount) + MULT_SIGN + L")"); + setText(*pnl_.m_staticTextRetryCount, L'(' + formatNumber(automaticRetryCount) + MULT_SIGN + L')'); pnl_.bSizerErrorsRetry->Show(automaticRetryCount > 0); //allow changing a few options dynamically during sync @@ -1104,10 +1104,10 @@ void SyncProgressDialogImpl<TopLevelDialog>::updateProgressGui(bool allowYield) else { setText(*pnl_.m_staticTextItemsProcessed, formatNumber(itemsCurrent), &layoutChanged); - setText(*pnl_.m_staticTextBytesProcessed, L"(" + formatFilesizeShort(bytesCurrent) + L")", &layoutChanged); + setText(*pnl_.m_staticTextBytesProcessed, L'(' + formatFilesizeShort(bytesCurrent) + L')', &layoutChanged); setText(*pnl_.m_staticTextItemsRemaining, formatNumber(itemsTotal - itemsCurrent), &layoutChanged); - setText(*pnl_.m_staticTextBytesRemaining, L"(" + formatFilesizeShort(bytesTotal - bytesCurrent) + L")", &layoutChanged); + setText(*pnl_.m_staticTextBytesRemaining, L'(' + formatFilesizeShort(bytesTotal - bytesCurrent) + L')', &layoutChanged); //it's possible data remaining becomes shortly negative if last file synced has ADS data and the bytesTotal was not yet corrected! } diff --git a/FreeFileSync/Source/ui/small_dlgs.cpp b/FreeFileSync/Source/ui/small_dlgs.cpp index 39855f3c..1e38285c 100644 --- a/FreeFileSync/Source/ui/small_dlgs.cpp +++ b/FreeFileSync/Source/ui/small_dlgs.cpp @@ -272,7 +272,7 @@ CloudSetupDlg::CloudSetupDlg(wxWindow* parent, Zstring& folderPathPhrase, size_t setupFileDrop(*m_panelAuth); m_panelAuth->Connect(EVENT_DROP_FILE, FileDropEventHandler(CloudSetupDlg::onKeyFileDropped), nullptr, this); - m_staticTextConnectionsLabelSub->SetLabel(L"(" + _("Connections") + L")"); + m_staticTextConnectionsLabelSub->SetLabel(L'(' + _("Connections") + L')'); //use spacer to keep dialog height stable, no matter if key file options are visible bSizerAuthInner->Add(0, m_panelAuth->GetSize().y); @@ -1123,7 +1123,7 @@ OptionsDlg::OptionsDlg(wxWindow* parent, XmlGlobalSettings& globalSettings) : m_bpButtonAddRow ->SetBitmapLabel(getResourceImage(L"item_add")); m_bpButtonRemoveRow ->SetBitmapLabel(getResourceImage(L"item_remove")); - m_staticTextAllDialogsShown->SetLabel(L"(" + _("All dialogs shown") + L")"); + m_staticTextAllDialogsShown->SetLabel(L'(' + _("All dialogs shown") + L')'); m_staticTextResetDialogs->Wrap(std::max(fastFromDIP(250), m_buttonRestoreDialogs ->GetSize().x + @@ -1667,7 +1667,7 @@ private: { const double fraction = bytesTotal_ == 0 ? 0 : 1.0 * bytesCurrent_ / bytesTotal_; m_staticTextHeader->SetLabel(_("Downloading update...") + L' ' + - numberTo<std::wstring>(numeric::round(fraction * 100)) + L"% (" + formatFilesizeShort(bytesCurrent_) + L")"); + numberTo<std::wstring>(numeric::round(fraction * 100)) + L"% (" + formatFilesizeShort(bytesCurrent_) + L')'); m_gaugeProgress->SetValue(numeric::round(fraction * GAUGE_FULL_RANGE)); m_staticTextDetails->SetLabel(utfTo<std::wstring>(filePath_)); diff --git a/FreeFileSync/Source/ui/sync_cfg.cpp b/FreeFileSync/Source/ui/sync_cfg.cpp index 318ec3b9..fe3c00da 100644 --- a/FreeFileSync/Source/ui/sync_cfg.cpp +++ b/FreeFileSync/Source/ui/sync_cfg.cpp @@ -356,7 +356,7 @@ showMultipleCfgs_(showMultipleCfgs) m_staticTextFilterDescr->Wrap(fastFromDIP(450)); enumTimeDescr_. - add(UnitTime::NONE, L"(" + _("None") + L")"). //meta options should be enclosed in parentheses + add(UnitTime::NONE, L'(' + _("None") + L')'). //meta options should be enclosed in parentheses add(UnitTime::TODAY, _("Today")). //add(UnitTime::THIS_WEEK, _("This week")). add(UnitTime::THIS_MONTH, _("This month")). @@ -364,7 +364,7 @@ showMultipleCfgs_(showMultipleCfgs) add(UnitTime::LAST_X_DAYS, _("Last x days:")); enumSizeDescr_. - add(UnitSize::NONE, L"(" + _("None") + L")"). //meta options should be enclosed in parentheses + add(UnitSize::NONE, L'(' + _("None") + L')'). //meta options should be enclosed in parentheses add(UnitSize::BYTE, _("Byte")). add(UnitSize::KB, _("KB")). add(UnitSize::MB, _("MB")); diff --git a/FreeFileSync/Source/version/version.h b/FreeFileSync/Source/version/version.h index 5496cd99..d101d97a 100644 --- a/FreeFileSync/Source/version/version.h +++ b/FreeFileSync/Source/version/version.h @@ -3,7 +3,7 @@ namespace fff { -const char ffsVersion[] = "10.21"; //internal linkage! +const char ffsVersion[] = "10.22"; //internal linkage! const char FFS_VERSION_SEPARATOR = '.'; } diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp index 91a881dc..eeebda53 100644 --- a/zen/format_unit.cpp +++ b/zen/format_unit.cpp @@ -191,7 +191,7 @@ std::wstring zen::formatNumber(int64_t n) std::wstring zen::formatUtcToLocalTime(time_t utcTime) { - auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; }; + auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L')'; }; TimeComp loc = getLocalTime(utcTime); diff --git a/zen/open_ssl.cpp b/zen/open_ssl.cpp index b823f8ca..0f1da3fc 100644 --- a/zen/open_ssl.cpp +++ b/zen/open_ssl.cpp @@ -18,7 +18,7 @@ using namespace zen; #error FFS, we are royally screwed! #endif -static_assert(OPENSSL_VERSION_NUMBER >= 0x10100000L, "OpenSSL version too old"); +static_assert(OPENSSL_VERSION_NUMBER >= 0x1010105fL, "OpenSSL version too old"); void zen::openSslInit() @@ -68,7 +68,7 @@ std::wstring formatOpenSSLError(const std::wstring& functionName, unsigned long std::wstring formatLastOpenSSLError(const std::wstring& functionName) { - const unsigned long ec = ::ERR_peek_last_error(); + const auto ec = ::ERR_peek_last_error(); ::ERR_clear_error(); //clean up for next OpenSSL operation on this thread return formatOpenSSLError(functionName, ec); } @@ -566,9 +566,16 @@ public: if (rv != 1) { const int sslError = ::SSL_get_error(ssl_, rv); - if (sslError == SSL_ERROR_ZERO_RETURN || //EOF + close_notify alert - (sslError == SSL_ERROR_SYSCALL && ::ERR_peek_last_error() == 0)) //EOF: only expected for HTTP/1.0 + if (sslError == SSL_ERROR_ZERO_RETURN) + return 0; //EOF + close_notify alert + + warn_static("find a better solution for SSL_read_ex + EOF") + //"sslError == SSL_ERROR_SYSCALL && ::ERR_peek_last_error() == 0" => obsolete as of OpenSSL 1.1.1e + //https://github.com/openssl/openssl/issues/10880#issuecomment-575746226 + 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; + throw SysError(formatLastOpenSSLError(L"SSL_read_ex") + L' ' + formatSslErrorCode(sslError)); } assert(bytesReceived > 0); //SSL_read_ex() considers EOF an error! @@ -764,7 +771,7 @@ std::string zen::convertPuttyKeyToPkix(const std::string& keyStream, const std:: auto numToBeString = [](size_t n) -> std::string { - static_assert(usingLittleEndian() && sizeof(n) >= 4); + static_assert(usingLittleEndian()&& sizeof(n) >= 4); const char* numStr = reinterpret_cast<const char*>(&n); return { numStr[3], numStr[2], numStr[1], numStr[0] }; //big endian! }; diff --git a/zen/string_base.h b/zen/string_base.h index d2e00baf..42e1bdf3 100644 --- a/zen/string_base.h +++ b/zen/string_base.h @@ -328,11 +328,11 @@ template <class Char, template <class> class SP> inline Zbase<Char, SP> operator template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(Zbase<Char, SP>&& lhs, const Char* rhs) { return std::move(lhs += rhs); } //lhs, is an l-value parameter... template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(Zbase<Char, SP>&& lhs, Char rhs) { return std::move(lhs += rhs); } //and not a local variable => no copy elision -template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+( Char lhs, const Zbase<Char, SP>& rhs) { return Zbase<Char, SP>(&lhs, 1) += rhs; } template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Char* lhs, const Zbase<Char, SP>& rhs) { return Zbase<Char, SP>(lhs ) += rhs; } +template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+( Char lhs, const Zbase<Char, SP>& rhs) { return Zbase<Char, SP>(&lhs, 1) += rhs; } - - +template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Zbase<Char, SP>&, int) = delete; //detect usage errors +template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(int, const Zbase<Char, SP>&) = delete; // @@ -567,6 +567,7 @@ template <class Char, template <class> class SP> inline Char& Zbase<Char, SP>::operator[](size_t pos) { assert(pos < length()); //design by contract! no runtime check! + reserve(length()); //make unshared! return rawStr_[pos]; } diff --git a/zen/zstring.cpp b/zen/zstring.cpp index 046a3bd4..82082df0 100644 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -59,7 +59,7 @@ Zstring getUnicodeNormalForm(const Zstring& str) { gchar* outStr = ::g_utf8_normalize(str.c_str(), str.length(), G_NORMALIZE_DEFAULT_COMPOSE); if (!outStr) - throw SysError(L"g_utf8_normalize: conversion failed. (" + utfTo<std::wstring>(str) + L")"); + throw SysError(L"g_utf8_normalize: conversion failed. (" + utfTo<std::wstring>(str) + L')'); ZEN_ON_SCOPE_EXIT(::g_free(outStr)); return outStr; |