[bookmarks] Use safe version of saving kml and kmb files.

This commit is contained in:
Daria Volvenkova 2020-03-02 19:37:48 +03:00 committed by Arsentiy Milchakov
parent b230d6fdc9
commit 702bd68334
5 changed files with 37 additions and 25 deletions

View file

@ -554,8 +554,9 @@ void BookmarkCatalog::Upload(UploadData uploadData, std::string const & accessTo
// Save KML.
auto const filePath = base::JoinPath(GetPlatform().TmpDir(), uploadData.m_serverId + kKmlExtension);
if (!SaveKmlFile(*fileData, filePath, KmlFileType::Text))
if (!SaveKmlFileSafe(*fileData, filePath, KmlFileType::Text))
{
FileWriter::DeleteFileX(filePath);
if (uploadErrorCallback)
uploadErrorCallback(UploadResult::InvalidCall, "Could not save the uploading file.");
return;

View file

@ -339,6 +339,22 @@ bool SaveKmlFile(kml::FileData & kmlData, std::string const & file, KmlFileType
return success;
}
bool SaveKmlFileSafe(kml::FileData & kmlData, std::string const & file, KmlFileType fileType)
{
auto const fileTmp = file + ".tmp";
if (SaveKmlFile(kmlData, fileTmp, fileType))
{
// Only after successful save we replace original file.
base::DeleteFileX(file);
auto const res = base::RenameFileX(fileTmp, file);
if (!res)
LOG(LWARNING, ("Renaming of .tmp bookmarks file failed", fileTmp, file));
return res;
}
base::DeleteFileX(fileTmp);
return false;
}
bool SaveKmlData(kml::FileData & kmlData, Writer & writer, KmlFileType fileType)
{
try

View file

@ -93,7 +93,7 @@ std::unique_ptr<kml::FileData> LoadKmlFile(std::string const & file, KmlFileType
std::unique_ptr<kml::FileData> LoadKmzFile(std::string const & file, std::string & kmlHash);
std::unique_ptr<kml::FileData> LoadKmlData(Reader const & reader, KmlFileType fileType);
bool SaveKmlFile(kml::FileData & kmlData, std::string const & file, KmlFileType fileType);
bool SaveKmlFileSafe(kml::FileData & kmlData, std::string const & file, KmlFileType fileType);
bool SaveKmlData(kml::FileData & kmlData, Writer & writer, KmlFileType fileType);
void ResetIds(kml::FileData & kmlData);

View file

@ -152,7 +152,7 @@ BookmarkManager::SharingResult GetFileForSharing(BookmarkManager::KMLDataCollect
auto const categoryId = kmlToShare.second->m_categoryData.m_id;
if (!SaveKmlFile(*kmlToShare.second, filePath, KmlFileType::Text))
if (!SaveKmlFileSafe(*kmlToShare.second, filePath, KmlFileType::Text))
{
return BookmarkManager::SharingResult(categoryId, BookmarkManager::SharingResult::Code::FileError,
"Bookmarks file does not exist.");
@ -187,7 +187,7 @@ Cloud::ConvertionResult ConvertBeforeUploading(std::string const & filePath,
return r;
}
if (!SaveKmlFile(*kmlData, tmpFilePath, KmlFileType::Text))
if (!SaveKmlFileSafe(*kmlData, tmpFilePath, KmlFileType::Text))
return {};
Cloud::ConvertionResult result;
@ -215,7 +215,7 @@ Cloud::ConvertionResult ConvertAfterDownloading(std::string const & filePath,
Cloud::ConvertionResult result;
result.m_hash = hash;
result.m_isSuccessful = SaveKmlFile(*kmlData, convertedFilePath, KmlFileType::Binary);
result.m_isSuccessful = SaveKmlFileSafe(*kmlData, convertedFilePath, KmlFileType::Binary);
return result;
}
@ -320,7 +320,7 @@ bool ConvertBookmarks(std::vector<std::string> const & files,
if (kmlData == nullptr)
continue;
if (!SaveKmlFile(*kmlData, kmbPath, KmlFileType::Binary))
if (!SaveKmlFileSafe(*kmlData, kmbPath, KmlFileType::Binary))
{
base::DeleteFileX(kmbPath);
continue;
@ -504,7 +504,7 @@ void FixUpHotelPlacemarks(BookmarkManager::KMLDataCollectionPtr & collection,
if (needSave)
{
CHECK(!p.first.empty(), ());
SaveKmlFile(*p.second, p.first, KmlFileType::Binary);
SaveKmlFileSafe(*p.second, p.first, KmlFileType::Binary);
}
}
@ -1911,7 +1911,7 @@ void BookmarkManager::LoadBookmarkRoutine(std::string const & filePath, bool isT
base::DeleteFileX(fileSavePath);
fileSavePath = GenerateValidAndUniqueFilePathForKMB(fileName);
if (!SaveKmlFile(*kmlData, fileSavePath, KmlFileType::Binary))
if (!SaveKmlFileSafe(*kmlData, fileSavePath, KmlFileType::Binary))
{
base::DeleteFileX(fileSavePath);
fileSavePath.clear();
@ -2398,6 +2398,8 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool
if (!UserMarkIdStorage::Instance().CheckIds(fileData) || HasDuplicatedIds(fileData))
{
LOG(LINFO, ("Reset bookmark ids in the file", fileName,
", the file is from catalog:", FromCatalog(fileData)));
//TODO: notify subscribers(like search subsystem). This KML could have been indexed.
ResetIds(fileData);
}
@ -2526,7 +2528,7 @@ bool BookmarkManager::SaveBookmarkCategory(kml::MarkGroupId groupId)
return false;
auto const & file = collection->front().first;
auto & kmlData = *collection->front().second;
return SaveKmlFileSafe(kmlData, file);
return SaveKmlFileByExt(kmlData, file);
}
bool BookmarkManager::SaveBookmarkCategory(kml::MarkGroupId groupId, Writer & writer,
@ -2588,20 +2590,11 @@ BookmarkManager::KMLDataCollectionPtr BookmarkManager::PrepareToSaveBookmarks(
return collection;
}
bool BookmarkManager::SaveKmlFileSafe(kml::FileData & kmlData, std::string const & file)
bool BookmarkManager::SaveKmlFileByExt(kml::FileData & kmlData, std::string const & file)
{
auto const ext = base::GetFileExtension(file);
auto const fileTmp = file + ".tmp";
if (SaveKmlFile(kmlData, fileTmp, ext == kKmbExtension ?
KmlFileType::Binary : KmlFileType::Text))
{
// Only after successful save we replace original file.
base::DeleteFileX(file);
VERIFY(base::RenameFileX(fileTmp, file), (fileTmp, file));
return true;
}
base::DeleteFileX(fileTmp);
return false;
return SaveKmlFileSafe(kmlData, file, ext == kKmbExtension ? KmlFileType::Binary
: KmlFileType::Text);
}
void BookmarkManager::SaveBookmarks(kml::GroupIdCollection const & groupIdCollection)
@ -2622,7 +2615,7 @@ void BookmarkManager::SaveBookmarks(kml::GroupIdCollection const & groupIdCollec
{
// Save bookmarks synchronously.
for (auto const & kmlItem : *kmlDataCollection)
SaveKmlFileSafe(*kmlItem.second, kmlItem.first);
SaveKmlFileByExt(*kmlItem.second, kmlItem.first);
return;
}
@ -2630,7 +2623,7 @@ void BookmarkManager::SaveBookmarks(kml::GroupIdCollection const & groupIdCollec
[this, kmlDataCollection = std::move(kmlDataCollection)]()
{
for (auto const & kmlItem : *kmlDataCollection)
SaveKmlFileSafe(*kmlItem.second, kmlItem.first);
SaveKmlFileByExt(*kmlItem.second, kmlItem.first);
});
}
@ -2846,8 +2839,9 @@ void BookmarkManager::ConvertAllKmlFiles(ConversionHandler && handler)
while (Platform::IsFileExistsByFullPath(kmbPath))
kmbPath = base::JoinPath(newDir, fileName + strings::to_string(counter++) + kKmbExtension);
if (!SaveKmlFile(*kmlData, kmbPath, KmlFileType::Binary))
if (!SaveKmlFileSafe(*kmlData, kmbPath, KmlFileType::Binary))
{
FileWriter::DeleteFileX(kmbPath);
allConverted = false;
continue;
}
@ -3192,6 +3186,7 @@ void BookmarkManager::UploadToCatalog(kml::MarkGroupId categoryId, kml::AccessRu
auto fileDataPtr = std::make_unique<kml::FileData>();
auto const serverId = fileData->m_serverId;
*fileDataPtr = std::move(*fileData);
LOG(LINFO, ("Reset bookmark ids after uploading, server id:", fileData->m_serverId));
ResetIds(*fileDataPtr);
KMLDataCollection collection;
collection.emplace_back(std::make_pair("", std::move(fileDataPtr)));

View file

@ -647,7 +647,7 @@ private:
std::unique_ptr<kml::FileData> CollectBmGroupKMLData(BookmarkCategory const * group) const;
KMLDataCollectionPtr PrepareToSaveBookmarks(kml::GroupIdCollection const & groupIdCollection);
bool SaveKmlFileSafe(kml::FileData & kmlData, std::string const & file);
bool SaveKmlFileByExt(kml::FileData & kmlData, std::string const & file);
void OnSynchronizationStarted(Cloud::SynchronizationType type);
void OnSynchronizationFinished(Cloud::SynchronizationType type, Cloud::SynchronizationResult result,