Skip to content

Commit

Permalink
Merge branch 'develop' into KDESKTOP-1283-kStore-Implement-Beta-and-I…
Browse files Browse the repository at this point in the history
…nternal-channel
  • Loading branch information
ClementKunz authored Jan 3, 2025
2 parents 50b1fc4 + e684783 commit 39b43a3
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 23 deletions.
8 changes: 7 additions & 1 deletion src/libcommon/utility/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ constexpr char loginItemAgentIdStr[] = "864VDCS2QY.com.infomaniak.drive.desktopc
#endif

namespace KDC {

std::mutex CommonUtility::_generateRandomStringMutex;

const int CommonUtility::logsPurgeRate = 7; // days
const int CommonUtility::logMaxSize = 500 * 1024 * 1024; // MB

Expand All @@ -86,7 +89,10 @@ static const QString italianCode = "it";
static std::random_device rd;
static std::default_random_engine gen(rd());

std::string generateRandomString(const char *charArray, std::uniform_int_distribution<int> &distrib, const int length /*= 10*/) {
std::string CommonUtility::generateRandomString(const char *charArray, std::uniform_int_distribution<int> &distrib,
const int length /*= 10*/) {
const std::lock_guard<std::mutex> lock(_generateRandomStringMutex);

std::string tmp;
tmp.reserve(static_cast<size_t>(length));
for (int i = 0; i < length; ++i) {
Expand Down
6 changes: 6 additions & 0 deletions src/libcommon/utility/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <string>
#include <thread>
#include <random>

#ifdef _WIN32
#include <strsafe.h>
Expand Down Expand Up @@ -137,6 +138,11 @@ struct COMMON_EXPORT CommonUtility {
#endif

private:
static std::mutex _generateRandomStringMutex;

static std::string generateRandomString(const char *charArray, std::uniform_int_distribution<int> &distrib,
const int length = 10);

static void extractIntFromStrVersion(const std::string &version, std::vector<int> &tabVersion);
};

Expand Down
51 changes: 33 additions & 18 deletions src/libsyncengine/jobs/network/API_v2/downloadjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,31 +199,37 @@ bool DownloadJob::handleResponse(std::istream &is) {
return false;
}
} else {
// Create/fetch normal file
#ifdef _WIN32
const std::string tmpFileName = tmpnam(nullptr);
#else
const std::string tmpFileName = "kdrive_" + CommonUtility::generateRandomStringAlphaNum();
#endif

SyncPath tmpPath;
SyncPath tmpDirectoryPath;
IoError ioError = IoError::Success;
if (!IoHelper::tempDirectoryPath(tmpPath, ioError)) {
LOGW_WARN(_logger, L"Failed to get temporary directory path: " << Utility::formatIoError(tmpPath, ioError));
if (!IoHelper::tempDirectoryPath(tmpDirectoryPath, ioError)) {
LOGW_WARN(_logger, L"Failed to get temporary directory path: " << Utility::formatIoError(tmpDirectoryPath, ioError));
_exitCode = ExitCode::SystemError;
_exitCause = ExitCause::Unknown;
return false;
}

tmpPath /= tmpFileName;
SyncPath tmpPath;
std::ofstream output;
do {
// Create/fetch normal file
#ifdef _WIN32
const std::string tmpFileName = tmpnam(nullptr);
#else
const std::string tmpFileName = "kdrive_" + CommonUtility::generateRandomStringAlphaNum();
#endif

std::ofstream output(tmpPath.native().c_str(), std::ios::binary);
if (!output) {
LOGW_WARN(_logger, L"Failed to create file: " << Utility::formatSyncPath(tmpPath));
_exitCode = ExitCode::SystemError;
_exitCause = Utility::enoughSpace(tmpPath) ? ExitCause::FileAccessError : ExitCause::NotEnoughDiskSpace;
return false;
}
tmpPath = tmpDirectoryPath / tmpFileName;

output.open(tmpPath.native().c_str(), std::ofstream::out | std::ofstream::binary);
if (!output.is_open()) {
LOGW_WARN(_logger, L"Failed to open tmp file: " << Utility::formatSyncPath(tmpPath));
_exitCode = ExitCode::SystemError;
_exitCause = Utility::enoughSpace(tmpPath) ? ExitCause::FileAccessError : ExitCause::NotEnoughDiskSpace;
return false;
}

output.seekp(0, std::ios_base::end);
} while (output.tellp() > 0); // If the file is not empty, generate a new file name

std::chrono::steady_clock::time_point fileProgressTimer = std::chrono::steady_clock::now();

Expand Down Expand Up @@ -316,6 +322,15 @@ bool DownloadJob::handleResponse(std::istream &is) {
}
}

// Checks that the file has not been corrupted by another process
// Unfortunately, the file hash is not available, so we check only its size
output.flush();
output.seekp(0, std::ios_base::end);
if (expectedSize != output.tellp()) {
LOG_WARN(_logger, "Request " << jobId() << ": tmp file has been corrupted by another process");
writeError = true;
}

output.close();
if (output.bad()) {
// Read/writing error or logical error
Expand Down
11 changes: 7 additions & 4 deletions src/libsyncengine/propagation/executor/executorworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,10 +2181,13 @@ ExitInfo ExecutorWorker::propagateEditToDbAndTree(SyncOpPtr syncOp, const NodeId
// that follow-up operations can execute correctly, as they are based on the
// information in this structure
if (!syncOp->omit()) {
_syncPal->updateTree(syncOp->targetSide())
->updateNodeId(syncOp->affectedNode(),
syncOp->targetSide() == ReplicaSide::Local ? localId : remoteId); // ID might have changed in the
// case of a delete+create
// ID might have changed in the case of a delete+create
if (!_syncPal->updateTree(syncOp->targetSide())
->updateNodeId(syncOp->affectedNode(), syncOp->targetSide() == ReplicaSide::Local ? localId : remoteId)) {
LOG_SYNCPAL_WARN(_logger, "Error in UpdateTreeWorker::updateNodeId");
return ExitCode::DataError;
}

syncOp->correspondingNode()->setLastModified(newLastModTime);
}
node = syncOp->correspondingNode();
Expand Down
39 changes: 39 additions & 0 deletions test/libcommon/utility/testutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,45 @@ void TestUtility::testCurrentVersion() {
CPPUNIT_ASSERT(std::regex_match(test, std::regex(R"(\d{1,2}\.{1}\d{1,2}\.{1}\d{1,2}\.{1}\d{0,8}$)")));
}

void TestUtility::testGenerateRandomStringAlphaNum() {
{
int err = 0;
std::set<std::string> results;
for (int i = 0; i < 100000; i++) {
std::string str = CommonUtility::generateRandomStringAlphaNum();
if (!results.insert(str).second) {
err++;
}
}
CPPUNIT_ASSERT(err == 0);
}

{
int err = 0;
for (int c = 0; c < 100000; c++) {
std::vector<std::thread> workers;
std::set<std::string> results;
std::mutex resultsMutex;
bool wait = true;
for (int i = 0; i < 3; i++) {
workers.push_back(std::thread([&]() {
while (wait) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
};
std::string str = CommonUtility::generateRandomStringAlphaNum();
const std::lock_guard<std::mutex> lock(resultsMutex);
if (!results.insert(str).second) {
err++;
}
}));
}
wait = false;
std::for_each(workers.begin(), workers.end(), [](std::thread &t) { t.join(); });
}
CPPUNIT_ASSERT(err == 0);
}
}

#ifdef _WIN32
void TestUtility::testGetLastErrorMessage() {
// No actual error. Display the expected success message.
Expand Down
2 changes: 2 additions & 0 deletions test/libcommon/utility/testutility.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class TestUtility : public CppUnit::TestFixture {
CPPUNIT_TEST(testArgsWriter);
CPPUNIT_TEST(testCompressFile);
CPPUNIT_TEST(testCurrentVersion);
CPPUNIT_TEST(testGenerateRandomStringAlphaNum);
#ifdef _WIN32
CPPUNIT_TEST(testGetLastErrorMessage);
#endif
Expand All @@ -43,6 +44,7 @@ class TestUtility : public CppUnit::TestFixture {
void testArgsWriter();
void testCompressFile();
void testCurrentVersion();
void testGenerateRandomStringAlphaNum();
#ifdef _WIN32
void testGetLastErrorMessage();
#endif
Expand Down

0 comments on commit 39b43a3

Please sign in to comment.