fix(vfs/cfapi): skip inserting new placeholder items with invalid mtime

filter new placeholder items by invalid modtime and only proceed with
creating only the valid ones

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2025-08-25 15:52:19 +02:00
parent 4c33454dda
commit 1b6c2e6805
2 changed files with 21 additions and 17 deletions

View File

@ -183,7 +183,7 @@ bool BulkPropagatorDownloadJob::start()
checkPropagationIsDone();
return !_filesToDownload.empty();
return false;
}
bool BulkPropagatorDownloadJob::updateMetadata(const SyncFileItemPtr &item)

View File

@ -908,16 +908,23 @@ OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholderInfo(const QStrin
OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholdersInfo(const QString &localBasePath, const QList<PlaceholdersInfo> &itemsInfo)
{
const auto stdWStringBasePath = localBasePath.toStdWString();
auto cloudEntry = std::make_unique<CF_PLACEHOLDER_CREATE_INFO[]>(itemsInfo.size());
auto filteredItemsInfo = QList<PlaceholdersInfo>{};
filteredItemsInfo.reserve(itemsInfo.size());
for(auto itemIndice = 0; itemIndice < itemsInfo.size(); ++itemIndice) {
const auto &placeholderInfo = itemsInfo[itemIndice];
if (placeholderInfo.modtime <= 0) {
return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(placeholderInfo.relativePath).arg(placeholderInfo.modtime)};
std::copy_if(itemsInfo.begin(), itemsInfo.end(), std::back_inserter(filteredItemsInfo), [] (const auto &onePlaceholderInfo) -> bool {
if (onePlaceholderInfo.modtime <= 0) {
qCWarning(lcCfApiWrapper()) << "Skip invalid modtime file: " << onePlaceholderInfo.relativePath << "modtime:" << onePlaceholderInfo.modtime;
return false;
}
return true;
});
const auto stdWStringBasePath = localBasePath.toStdWString();
auto cloudEntry = std::make_unique<CF_PLACEHOLDER_CREATE_INFO[]>(filteredItemsInfo.size());
for(auto itemIndice = 0; itemIndice < filteredItemsInfo.size(); ++itemIndice) {
const auto &placeholderInfo = filteredItemsInfo[itemIndice];
cloudEntry[itemIndice].FileIdentity = placeholderInfo.fileId.data();
cloudEntry[itemIndice].FileIdentityLength = static_cast<DWORD>(placeholderInfo.fileId.length());
@ -935,29 +942,26 @@ OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholdersInfo(const QStri
cloudEntry[itemIndice].FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
cloudEntry[itemIndice].FsMetadata.FileSize.QuadPart = 0;
}
qCDebug(lcCfApiWrapper) << "CfCreatePlaceholders" << stdWStringBasePath << placeholderInfo.platformNativeRelativePath << placeholderInfo.modtime << placeholderInfo.size;
qCDebug(lcCfApiWrapper) << QString::fromStdWString(cloudEntry[itemIndice].RelativeFileName);
}
auto numberOfCreatedPlaceholders = 0ul;
const qint64 result = CfCreatePlaceholders(stdWStringBasePath.data(), cloudEntry.get(), itemsInfo.size(), CF_CREATE_FLAG_NONE, &numberOfCreatedPlaceholders);
const qint64 result = CfCreatePlaceholders(stdWStringBasePath.data(), cloudEntry.get(), filteredItemsInfo.size(), CF_CREATE_FLAG_NONE, &numberOfCreatedPlaceholders);
if (result != S_OK) {
qCWarning(lcCfApiWrapper) << "Couldn't create placeholders info" << ":" << QString::fromWCharArray(_com_error(result).ErrorMessage()) << "number of placeholders created:" << numberOfCreatedPlaceholders;
for(auto itemIndice = 0; itemIndice < itemsInfo.size(); ++itemIndice) {
for(auto itemIndice = 0; itemIndice < filteredItemsInfo.size(); ++itemIndice) {
qCDebug(lcCfApiWrapper) << QString::fromStdWString(cloudEntry[itemIndice].RelativeFileName) << QString::fromWCharArray(_com_error(cloudEntry[itemIndice].Result).ErrorMessage());
}
return { "Couldn't create placeholder info" };
}
for(auto itemIndice = 0; itemIndice < itemsInfo.size(); ++itemIndice) {
const auto &placeholderInfo = itemsInfo[itemIndice];
const auto parentInfo = findPlaceholderInfo(QDir::toNativeSeparators(QFileInfo(localBasePath + placeholderInfo.relativePath).absolutePath()));
for(auto itemIndice = 0; itemIndice < filteredItemsInfo.size(); ++itemIndice) {
const auto &placeholderInfo = filteredItemsInfo[itemIndice];
const auto parentInfo = findPlaceholderInfo(QDir::toNativeSeparators(QFileInfo(localBasePath + QDir::separator() + placeholderInfo.relativePath).absolutePath()));
const auto state = parentInfo && parentInfo->PinState == CF_PIN_STATE_UNPINNED ? CF_PIN_STATE_UNPINNED : CF_PIN_STATE_INHERIT;
if (!setPinState(placeholderInfo.relativePath, cfPinStateToPinState(state), NoRecurse)) {
if (!setPinState(QDir::toNativeSeparators(QFileInfo(localBasePath + QDir::separator() + placeholderInfo.relativePath).absoluteFilePath()), cfPinStateToPinState(state), NoRecurse)) {
return { "Couldn't set the default inherit pin state" };
}
}