Core: Fix flaw in XMLReader class

Remove implementation details of the Document class from the XMLReader class.
Instead keep an array of failed files and check them in the calling instance.
This commit is contained in:
wmayer
2024-11-16 14:47:56 +01:00
committed by wwmayer
parent 89d1d717eb
commit 6f8abe880c
4 changed files with 26 additions and 9 deletions

View File

@@ -1007,7 +1007,8 @@ void Document::Restore(Base::XMLReader &reader)
if (reader.hasAttribute("StringHasher")) {
d->Hasher->Restore(reader);
} else {
}
else {
d->Hasher->clear();
}
@@ -1075,6 +1076,17 @@ void Document::Restore(Base::XMLReader &reader)
reader.readEndElement("Document");
}
void DocumentP::checkStringHasher(const Base::XMLReader& reader)
{
if (reader.hasReadFailed("StringHasher.Table.txt")) {
Base::Console().Error(QT_TRANSLATE_NOOP(
"Notifications",
"\nIt is recommended that the user right-click the root of "
"the document and select Mark to recompute.\n"
"The user should then click the Refresh button in the main toolbar.\n"));
}
}
std::pair<bool,int> Document::addStringHasher(const StringHasherRef & hasher) const {
if (!hasher)
return std::make_pair(false, 0);
@@ -2118,6 +2130,8 @@ void Document::restore (const char *filename,
signalRestoreDocument(reader);
reader.readFiles(zipstream);
DocumentP::checkStringHasher(reader);
if (reader.testStatus(Base::XMLReader::ReaderStatus::PartialRestore)) {
setStatus(Document::PartialRestore, true);
Base::Console().Error("There were errors while loading the file. Some data might have been modified or not recovered at all. Look above for more specific information about the objects involved.\n");

View File

@@ -144,6 +144,7 @@ struct DocumentP
topologicalSort(const std::vector<App::DocumentObject*>& objects) const;
std::vector<App::DocumentObject*>
static partialTopologicalSort(const std::vector<App::DocumentObject*>& objects);
static void checkStringHasher(const Base::XMLReader& reader);
};
} // namespace App

View File

@@ -38,7 +38,6 @@
#include "Persistence.h"
#include "Sequencer.h"
#include "Stream.h"
#include "Tools.h"
#include "XMLTools.h"
#ifdef _MSC_VER
@@ -438,13 +437,7 @@ void Base::XMLReader::readFiles(zipios::ZipInputStream& zipstream) const
// failure.
Base::Console().Error("Reading failed from embedded file: %s\n",
entry->toString().c_str());
if (jt->FileName == "StringHasher.Table.txt") {
Base::Console().Error(QT_TRANSLATE_NOOP(
"Notifications",
"\nIt is recommended that the user right-click the root of "
"the document and select Mark to recompute.\n"
"The user should then click the Refresh button in the main toolbar.\n"));
}
FailedFiles.push_back(jt->FileName);
}
// Go to the next registered file name
it = jt + 1;
@@ -480,6 +473,12 @@ const std::vector<std::string>& Base::XMLReader::getFilenames() const
return FileNames;
}
bool Base::XMLReader::hasReadFailed(const std::string& filename) const
{
auto it = std::find(FailedFiles.begin(), FailedFiles.end(), filename);
return (it != FailedFiles.end());
}
bool Base::XMLReader::isRegistered(Base::Persistence* Object) const
{
if (Object) {

View File

@@ -253,6 +253,8 @@ public:
void readFiles(zipios::ZipInputStream& zipstream) const;
/// get all registered file names
const std::vector<std::string>& getFilenames() const;
/// returns true if reading the file \a filename has failed
bool hasReadFailed(const std::string& filename) const;
bool isRegistered(Base::Persistence* Object) const;
virtual void addName(const char*, const char*);
virtual const char* getName(const char*) const;
@@ -363,6 +365,7 @@ public:
private:
std::vector<std::string> FileNames;
mutable std::vector<std::string> FailedFiles;
std::bitset<32> StatusBits;