summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wilhelm <shieldwed@outlook.com>2020-03-20 22:40:40 +0000
committerDaniel Wilhelm <shieldwed@outlook.com>2020-03-20 22:40:40 +0000
commit7a3869712e5c23b8e5e17ece4cbbf3d5909de5a6 (patch)
treea43b1c04f9947fe02d7d5444354f0176c28ed594
parentMerge branch '10.21' into 'master' (diff)
parentadd upstream 10.22 (diff)
downloadFreeFileSync-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-xChangelog.txt5
-rw-r--r--FreeFileSync/Source/afs/ftp.cpp22
-rw-r--r--FreeFileSync/Source/afs/gdrive.cpp18
-rw-r--r--FreeFileSync/Source/application.cpp5
-rw-r--r--FreeFileSync/Source/base/db_file.cpp2
-rw-r--r--FreeFileSync/Source/fatal_error.h2
-rw-r--r--FreeFileSync/Source/log_file.cpp2
-rw-r--r--FreeFileSync/Source/ui/abstract_folder_picker.cpp2
-rw-r--r--FreeFileSync/Source/ui/folder_pair.h8
-rw-r--r--FreeFileSync/Source/ui/log_panel.cpp6
-rw-r--r--FreeFileSync/Source/ui/main_dlg.cpp12
-rw-r--r--FreeFileSync/Source/ui/progress_indicator.cpp12
-rw-r--r--FreeFileSync/Source/ui/small_dlgs.cpp6
-rw-r--r--FreeFileSync/Source/ui/sync_cfg.cpp4
-rw-r--r--FreeFileSync/Source/version/version.h2
-rw-r--r--zen/format_unit.cpp2
-rw-r--r--zen/open_ssl.cpp17
-rw-r--r--zen/string_base.h7
-rw-r--r--zen/zstring.cpp2
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;
bgstack15