summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2022-12-16 21:08:02 -0500
committerB. Stack <bgstack15@gmail.com>2022-12-16 21:08:02 -0500
commitd35a4795f16e51f5773d00dce796f6948f82dae2 (patch)
treeb37279f6f8b354407507cc1a0e44691d6c63ffe8 /zen
parentadd upstream 11.28 (diff)
downloadFreeFileSync-11.29.tar.gz
FreeFileSync-11.29.tar.bz2
FreeFileSync-11.29.zip
add upstream 11.2911.29
Diffstat (limited to 'zen')
-rw-r--r--zen/file_access.cpp3
-rw-r--r--zen/legacy_compiler.h2
-rw-r--r--zen/open_ssl.cpp16
-rw-r--r--zen/open_ssl.h2
-rw-r--r--zen/resolve_path.cpp6
-rw-r--r--zen/serialize.h5
-rw-r--r--zen/string_base.h72
-rw-r--r--zen/sys_info.cpp2
8 files changed, 67 insertions, 41 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp
index 01dda68c..0c28f325 100644
--- a/zen/file_access.cpp
+++ b/zen/file_access.cpp
@@ -200,6 +200,9 @@ void zen::removeDirectoryPlain(const Zstring& dirPath) //throw FileError
THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot delete directory %x."), L"%x", fmtPath(dirPath)), "unlink");
return;
}
+ //if (ec == ERROR_SHARING_VIOLATION) => getLockingProcesses() can't handle directory paths! :( RmGetList() fails with ERROR_ACCESS_DENIED
+ //https://blog.yaakov.online/failed-experiment-what-processes-have-a-lock-on-this-folder/
+
throw FileError(replaceCpy(_("Cannot delete directory %x."), L"%x", fmtPath(dirPath)), formatSystemError(functionName, ec));
}
/* Windows: may spuriously fail with ERROR_DIR_NOT_EMPTY(145) even though all child items have
diff --git a/zen/legacy_compiler.h b/zen/legacy_compiler.h
index 8f93153e..8606f95c 100644
--- a/zen/legacy_compiler.h
+++ b/zen/legacy_compiler.h
@@ -35,7 +35,7 @@ basic_string<Char, Traits, Alloc> operator+(basic_string<Char, Traits, Alloc>&&
//template <class Char> inline
//basic_string<Char> operator+(const basic_string<Char>& lhs, const basic_string_view<Char>& rhs) { return basic_string<Char>(lhs) + rhs; }
-//-> somewhat inefficient: enable + optimize when needed
+//-> somewhat inefficient: single memory allocation should suffice!!!
}
//---------------------------------------------------------------------------------
diff --git a/zen/open_ssl.cpp b/zen/open_ssl.cpp
index 1f556656..9278b6dd 100644
--- a/zen/open_ssl.cpp
+++ b/zen/open_ssl.cpp
@@ -151,7 +151,13 @@ std::shared_ptr<EVP_PKEY> streamToKey(const std::string& keyStream, RsaStreamTyp
throw SysError(formatLastOpenSSLError("OSSL_DECODER_CTX_new_for_pkey"));
ZEN_ON_SCOPE_EXIT(::OSSL_DECODER_CTX_free(decCtx));
- //key stream is password-protected? => OSSL_DECODER_CTX_set_passphrase()
+#if 0 //key stream is password-protected? => OSSL_DECODER_CTX_set_passphrase()
+ if (!password.empty())
+ if (::OSSL_DECODER_CTX_set_passphrase(decCtx, //OSSL_DECODER_CTX *ctx
+ reinterpret_cast<const unsigned char*>(password.c_str()), //const unsigned char* kstr
+ password.size()) != 1) //size_t klen
+ throw SysError(formatLastOpenSSLError("OSSL_DECODER_CTX_set_passphrase"));
+#endif
const unsigned char* keyBuf = reinterpret_cast<const unsigned char*>(keyStream.c_str());
size_t keyLen = keyStream.size();
@@ -409,11 +415,9 @@ void zen::verifySignature(const std::string& message, const std::string& signatu
}
-bool zen::isPuttyKeyStream(const std::string& keyStream)
+bool zen::isPuttyKeyStream(const std::string_view keyStream)
{
- std::string firstLine(keyStream.begin(), std::find_if(keyStream.begin(), keyStream.end(), isLineBreak<char>));
- trim(firstLine);
- return startsWith(firstLine, "PuTTY-User-Key-File-2:");
+ return startsWith(trimCpy(keyStream, true, false), "PuTTY-User-Key-File-");
}
@@ -548,7 +552,7 @@ std::string zen::convertPuttyKeyToPkix(const std::string& keyStream, const std::
auto numToBeString = [](size_t n) -> std::string
{
- static_assert(std::endian::native == std::endian::little && sizeof(n) >= 4);
+ static_assert(std::endian::native == std::endian::little&& 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/open_ssl.h b/zen/open_ssl.h
index c66ad9c0..1a28f068 100644
--- a/zen/open_ssl.h
+++ b/zen/open_ssl.h
@@ -33,7 +33,7 @@ void verifySignature(const std::string& message,
std::string convertRsaKey(const std::string& keyStream, RsaStreamType typeFrom, RsaStreamType typeTo, bool publicKey); //throw SysError
-bool isPuttyKeyStream(const std::string& keyStream);
+bool isPuttyKeyStream(const std::string_view keyStream);
std::string convertPuttyKeyToPkix(const std::string& keyStream, const std::string& passphrase); //throw SysError
}
diff --git a/zen/resolve_path.cpp b/zen/resolve_path.cpp
index 99e2f6c6..8b81e184 100644
--- a/zen/resolve_path.cpp
+++ b/zen/resolve_path.cpp
@@ -179,7 +179,7 @@ namespace
//expand volume name if possible, return original input otherwise
-Zstring expandVolumeName(Zstring pathPhrase) // [volname]:\folder [volname]\folder [volname]folder -> C:\folder
+Zstring tryExpandVolumeName(Zstring pathPhrase) // [volname]:\folder [volname]\folder [volname]folder -> C:\folder
{
//we only expect the [.*] pattern at the beginning => do not touch dir names like "C:\somedir\[stuff]"
trim(pathPhrase, true, false);
@@ -205,7 +205,7 @@ std::vector<Zstring> zen::getPathPhraseAliases(const Zstring& itemPath)
{
//should use a replaceCpy() that considers "local path" case-sensitivity (if only we had one...)
if (contains(itemPath, macroPath))
- pathAliases.push_back(makePathPhrase(replaceCpyAsciiNoCase(itemPath, macroPath, MACRO_SEP + Zstring(macroName) + MACRO_SEP)));
+ pathAliases.push_back(makePathPhrase(replaceCpyAsciiNoCase(itemPath, macroPath, Zstring() + MACRO_SEP + macroName + MACRO_SEP)));
};
for (const Zchar* envName :
@@ -242,7 +242,7 @@ Zstring zen::getResolvedFilePath(const Zstring& pathPhrase) //noexcept
trim(path); //remove leading/trailing whitespace before allowing misinterpretation in applyLongPathPrefix()
{
- path = expandVolumeName(path); //may block for slow USB sticks and idle HDDs!
+ path = tryExpandVolumeName(path); //may block for slow USB sticks and idle HDDs!
/* need to resolve relative paths:
WINDOWS:
diff --git a/zen/serialize.h b/zen/serialize.h
index dd393422..a996b118 100644
--- a/zen/serialize.h
+++ b/zen/serialize.h
@@ -301,15 +301,16 @@ void unbufferedStreamCopy(Function1 tryRead /*(void* buffer, size_t bytesToRead)
Function2 tryWrite /*(const void* buffer, size_t bytesToWrite) throw X; may return short*/,
size_t blockSizeOut) //throw X
{
- /* caveat: buffer block sizes might not be power of 2:
+ /* caveat: buffer block sizes might not be a power of 2:
- f_iosize for network share on macOS
- libssh2 uses weird packet sizes like MAX_SFTP_OUTGOING_SIZE (30000), and will send incomplete packages if block size is not an exact multiple :(
+ - MTP uses file size as blocksize if under 256 kB (=> can be as small as 1 byte! https://freefilesync.org/forum/viewtopic.php?t=9823)
=> that's a problem because we want input/output sizes to be multiples of each other to help avoid the std::memmove() below */
#if 0
blockSizeIn = std::bit_ceil(blockSizeIn);
blockSizeOut = std::bit_ceil(blockSizeOut);
#endif
- if (blockSizeIn <= 1 || blockSizeOut <= 1)
+ if (blockSizeIn == 0 || blockSizeOut == 0)
throw std::logic_error("Contract violation! " + std::string(__FILE__) + ':' + numberTo<std::string>(__LINE__));
const size_t bufCapacity = blockSizeOut - 1 + blockSizeIn;
diff --git a/zen/string_base.h b/zen/string_base.h
index 3ebf848a..676d7f7f 100644
--- a/zen/string_base.h
+++ b/zen/string_base.h
@@ -61,11 +61,11 @@ protected:
~StorageDeepCopy() {}
Char* create(size_t size) { return create(size, size); }
- Char* create(size_t size, size_t capacity)
+ Char* create(size_t size, size_t minCapacity)
{
- assert(size <= capacity);
- const size_t newCapacity = AP::calcCapacity(capacity);
- assert(newCapacity >= capacity);
+ assert(size <= minCapacity);
+ const size_t newCapacity = AP::calcCapacity(minCapacity);
+ assert(newCapacity >= minCapacity);
Descriptor* const newDescr = static_cast<Descriptor*>(this->allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(Char))); //throw std::bad_alloc
new (newDescr) Descriptor(size, newCapacity);
@@ -124,18 +124,18 @@ protected:
~StorageRefCountThreadSafe() {}
Char* create(size_t size) { return create(size, size); }
- Char* create(size_t size, size_t capacity)
+ Char* create(size_t size, size_t minCapacity)
{
- assert(size <= capacity);
+ assert(size <= minCapacity);
- if (capacity == 0) //perf: avoid memory allocation for empty string
+ if (minCapacity == 0) //perf: avoid memory allocation for empty string
{
++globalEmptyString.descr.refCount;
return &globalEmptyString.nullTerm;
}
- const size_t newCapacity = AP::calcCapacity(capacity);
- assert(newCapacity >= capacity);
+ const size_t newCapacity = AP::calcCapacity(minCapacity);
+ assert(newCapacity >= minCapacity);
Descriptor* const newDescr = static_cast<Descriptor*>(this->allocate(sizeof(Descriptor) + (newCapacity + 1) * sizeof(Char))); //throw std::bad_alloc
new (newDescr) Descriptor(size, newCapacity);
@@ -230,8 +230,8 @@ public:
Zbase(const Char* str, size_t len) : Zbase(str, str + len) {}
explicit Zbase(const std::basic_string_view<Char> view) : Zbase(view.begin(), view.end()) {}
Zbase(size_t count, Char fillChar);
- template <class InputIterator>
- Zbase(InputIterator first, InputIterator last);
+ template <class RandomAccessIterator>
+ Zbase(RandomAccessIterator first, RandomAccessIterator last);
Zbase(const Zbase& str);
Zbase(Zbase&& tmp) noexcept;
//explicit Zbase(Char ch); //dangerous if implicit: Char buffer[]; return buffer[0]; ups... forgot &, but not a compiler error! //-> non-standard extension!!!
@@ -241,7 +241,7 @@ public:
//operator const Char* () const; //NO implicit conversion to a C-string!! Many problems... one of them: if we forget to provide operator overloads, it'll just work with a Char*...
operator std::basic_string_view<Char>() const& noexcept { return {data(), size()}; }
- operator std::basic_string_view<Char>() const&& = delete; //=> probably a bug!
+ //operator std::basic_string_view<Char>() const&& = delete; //=> probably a bug!
//STL accessors
using iterator = Char*;
@@ -281,8 +281,8 @@ public:
Zbase& assign(const Char* str, size_t len) { return assign(str, str + len); }
Zbase& append(const Char* str, size_t len) { return append(str, str + len); }
- template <class InputIterator> Zbase& assign(InputIterator first, InputIterator last);
- template <class InputIterator> Zbase& append(InputIterator first, InputIterator last);
+ template <class RandomAccessIterator> Zbase& assign(RandomAccessIterator first, RandomAccessIterator last);
+ template <class RandomAccessIterator> Zbase& append(RandomAccessIterator first, RandomAccessIterator last);
void resize(size_t newSize, Char fillChar = 0);
void swap(Zbase& str) { std::swap(rawStr_, str.rawStr_); }
@@ -296,21 +296,31 @@ public:
Zbase& operator+=(const Zbase& str) { return append(str.c_str(), str.size()); }
Zbase& operator+=(const Char* str) { return append(str, strLength(str)); }
Zbase& operator+=(Char ch) { return append(&ch, 1); }
+ Zbase& operator+=(const std::basic_string_view<Char> str) { return append(str.begin(), str.end()); }
static const size_t npos = static_cast<size_t>(-1);
+ inline friend Zbase operator+( const Char* lhs, const Zbase& rhs) { return Zbase(lhs, strLength(lhs), rhs.c_str(), rhs.size()); }
+ inline friend Zbase operator+( Char lhs, const Zbase& rhs) { return Zbase(&lhs, 1, rhs.c_str(), rhs.size()); }
+ inline friend Zbase operator+(const std::basic_string_view<Char> lhs, const Zbase& rhs) { return Zbase(lhs.data(), lhs.size(), rhs.c_str(), rhs.size()); }
+
private:
Zbase (int) = delete; //
Zbase(size_t count, int) = delete; //
Zbase& operator= (int) = delete; //detect usage errors by creating an intentional ambiguity with "Char"
Zbase& operator+= (int) = delete; //
void push_back (int) = delete; //
+
Zbase (std::nullptr_t) = delete;
Zbase(size_t count, std::nullptr_t) = delete;
Zbase& operator= (std::nullptr_t) = delete;
Zbase& operator+= (std::nullptr_t) = delete;
void push_back (std::nullptr_t) = delete;
+ //not part of std::string API => private:
+ Zbase(const Char* str1, size_t len1, const Char* str2, size_t len2);
+ //alternative: Zbase() + reserve() + 2 x append()
+
Char* rawStr_;
};
@@ -328,14 +338,13 @@ template <class Char, template <class> class SP> std::strong_ordering operator<=
template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Zbase<Char, SP>& lhs, const Zbase<Char, SP>& rhs) { return Zbase<Char, SP>(lhs) += rhs; }
template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Zbase<Char, SP>& lhs, const Char* rhs) { return Zbase<Char, SP>(lhs) += rhs; }
template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Zbase<Char, SP>& lhs, Char rhs) { return Zbase<Char, SP>(lhs) += rhs; }
+template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(const Zbase<Char, SP>& lhs, const std::basic_string_view<Char> rhs) { return Zbase<Char, SP>(lhs) += rhs; }
//don't use unified first argument but save one move-construction in the r-value case instead!
template <class Char, template <class> class SP> inline Zbase<Char, SP> operator+(Zbase<Char, SP>&& lhs, const Zbase<Char, SP>& rhs) { return std::move(lhs += rhs); } //the move *is* needed!!!
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+(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+(Zbase<Char, SP>&& lhs, const std::basic_string_view<Char> rhs) { return std::move(lhs += 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; //
@@ -359,8 +368,8 @@ Zbase<Char, SP>::Zbase()
template <class Char, template <class> class SP>
-template <class InputIterator> inline
-Zbase<Char, SP>::Zbase(InputIterator first, InputIterator last)
+template <class RandomAccessIterator> inline
+Zbase<Char, SP>::Zbase(RandomAccessIterator first, RandomAccessIterator last)
{
rawStr_ = this->create(last - first);
*std::copy(first, last, rawStr_) = 0;
@@ -393,6 +402,15 @@ Zbase<Char, SP>::Zbase(Zbase<Char, SP>&& tmp) noexcept
template <class Char, template <class> class SP> inline
+Zbase<Char, SP>::Zbase(const Char* str1, size_t len1, const Char* str2, size_t len2)
+{
+ rawStr_ = this->create(len1 + len2);
+ std::copy (str1, str1 + len1, rawStr_);
+ *std::copy(str2, str2 + len2, rawStr_ + len1) = 0;
+}
+
+
+template <class Char, template <class> class SP> inline
Zbase<Char, SP>::~Zbase()
{
static_assert(noexcept(this->~Zbase())); //has exception spec of compiler-generated destructor by default
@@ -568,7 +586,7 @@ void Zbase<Char, SP>::reserve(size_t minCapacity) //make unshared and check capa
//allocate a new string
const size_t len = size();
Char* newStr = this->create(len, std::max(len, minCapacity)); //reserve() must NEVER shrink the string: logical const!
- std::copy(rawStr_, rawStr_ + len + 1 /*0-termination*/, newStr);
+ *std::copy(rawStr_, rawStr_ + len , newStr) = 0;
this->destroy(rawStr_);
rawStr_ = newStr;
@@ -577,10 +595,10 @@ void Zbase<Char, SP>::reserve(size_t minCapacity) //make unshared and check capa
template <class Char, template <class> class SP>
-template <class InputIterator> inline
-Zbase<Char, SP>& Zbase<Char, SP>::assign(InputIterator first, InputIterator last)
+template <class RandomAccessIterator> inline
+Zbase<Char, SP>& Zbase<Char, SP>::assign(RandomAccessIterator first, RandomAccessIterator last)
{
- const size_t len = std::distance(first, last);
+ const size_t len = last - first;
if (this->canWrite(rawStr_, len))
{
*std::copy(first, last, rawStr_) = 0;
@@ -594,10 +612,10 @@ Zbase<Char, SP>& Zbase<Char, SP>::assign(InputIterator first, InputIterator last
template <class Char, template <class> class SP>
-template <class InputIterator> inline
-Zbase<Char, SP>& Zbase<Char, SP>::append(InputIterator first, InputIterator last)
+template <class RandomAccessIterator> inline
+Zbase<Char, SP>& Zbase<Char, SP>::append(RandomAccessIterator first, RandomAccessIterator last)
{
- const size_t len = std::distance(first, last);
+ const size_t len = last - first; //std::distance(first, last);
if (len > 0) //avoid making this string unshared for no reason
{
const size_t thisLen = size();
@@ -622,7 +640,7 @@ Zbase<Char, SP>& Zbase<Char, SP>::operator=(const Zbase<Char, SP>& str)
template <class Char, template <class> class SP> inline
Zbase<Char, SP>& Zbase<Char, SP>::operator=(Zbase<Char, SP>&& tmp) noexcept
{
- //don't use swap() but end rawStr_ life time immediately
+ //don't swap() but end rawStr_ life time immediately
this->destroy(rawStr_);
rawStr_ = std::exchange(tmp.rawStr_, nullptr);
diff --git a/zen/sys_info.cpp b/zen/sys_info.cpp
index 5a044c3a..df0e4612 100644
--- a/zen/sys_info.cpp
+++ b/zen/sys_info.cpp
@@ -225,7 +225,7 @@ Zstring zen::getUserHome() //throw FileError
return homePath;
//root(0) => consider as request for elevation, NOT impersonation!
- //=> no support for HOME variable :(
+ //=> "HOME=/root" :(
const Zstring loginUser = getLoginUser(); //throw FileError
bgstack15