diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 832970833..ed2498545 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -597,32 +597,35 @@ void SearchDialog::collOpen() if (rsFiles->FileDetails(hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE - | RS_FILE_HINTS_SPEC_ONLY, info)) { - + | RS_FILE_HINTS_SPEC_ONLY, info)) + { /* make path for downloaded files */ std::string path; path = info.path; /* open file with a suitable application */ QFileInfo qinfo; + RsCollection::RsCollectionErrorCode err; qinfo.setFile(QString::fromUtf8(path.c_str())); - if (qinfo.exists()) { - if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) { - RsCollection collection; - if (collection.load(qinfo.absoluteFilePath())) { - collection.downloadFiles(); - return; - } - } - } + if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) + RsCollection(qinfo.absoluteFilePath(),err).downloadFiles(); } } } - RsCollection collection; - if (collection.load(this)) { - collection.downloadFiles(); - }//if (collection.load(this)) + QString fileName; + if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName)) + return ; + + std::cerr << "Got file name: " << fileName.toStdString() << std::endl; + + RsCollection::RsCollectionErrorCode err; + RsCollection collection(fileName, err); + + if(err == RsCollection::RsCollectionErrorCode::NO_ERROR) + collection.downloadFiles(); + else + QMessageBox::information(nullptr,tr("Error open RsCollection file"),RsCollection::errorString(err)); } void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString &base) diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp index 5abe9ab39..4645841a9 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp @@ -652,7 +652,7 @@ void SharedFilesDialog::copyLinks(const QModelIndexList& lst, bool remote,QList< QString dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName(); - RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->mTotalSize,ft->mTotalFiles,QString::fromStdString(ft->toRadix64())) ; + RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->totalFileSize(),ft->numFiles(),QString::fromStdString(ft->toRadix64())) ; if(link.valid()) urls.push_back(link) ; @@ -821,8 +821,12 @@ void SharedFilesDialog::collOpen() qinfo.setFile(QString::fromUtf8(path.c_str())); if (qinfo.exists()) { if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) { - RsCollection collection; - if (collection.load(qinfo.absoluteFilePath())) { + + RsCollection::RsCollectionErrorCode err; + RsCollection collection(qinfo.absoluteFilePath(),err); + + if(err == RsCollection::RsCollectionErrorCode::NO_ERROR) + { collection.downloadFiles(); return; } @@ -831,10 +835,17 @@ void SharedFilesDialog::collOpen() } } - RsCollection collection; - if (collection.load(this)) { + QString fileName; + if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName)) + return ; + + std::cerr << "Got file name: " << fileName.toStdString() << std::endl; + + RsCollection::RsCollectionErrorCode err; + RsCollection collection(fileName,err); + + if(err == RsCollection::RsCollectionErrorCode::NO_ERROR) collection.downloadFiles(); - } } void LocalSharedFilesDialog::playselectedfiles() diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index 6fc45a070..8dca82e28 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -2564,23 +2564,29 @@ void TransfersDialog::collOpen() /* open file with a suitable application */ QFileInfo qinfo; qinfo.setFile(QString::fromUtf8(path.c_str())); - if (qinfo.exists()) { - if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) { - RsCollection collection; - if (collection.load(qinfo.absoluteFilePath())) { - collection.downloadFiles(); - return; - } - } - } + if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) + { + RsCollection::RsCollectionErrorCode code; + RsCollection(qinfo.absoluteFilePath(),code).downloadFiles(); + return; + } } } } - RsCollection collection; - if (collection.load(this)) { + QString fileName; + if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName)) + return ; + + std::cerr << "Got file name: " << fileName.toStdString() << std::endl; + + RsCollection::RsCollectionErrorCode code; + RsCollection collection(fileName,code); + + if(code == RsCollection::RsCollectionErrorCode::NO_ERROR) collection.downloadFiles(); - } + else + QMessageBox::information(nullptr,tr("Error openning collection file"),RsCollection::errorString(code)); } void TransfersDialog::collAutoOpen(const QString &fileHash) @@ -2592,21 +2598,18 @@ void TransfersDialog::collAutoOpen(const QString &fileHash) if (rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) { /* make path for downloaded files */ - if (info.downloadStatus == FT_STATE_COMPLETE) { + if (info.downloadStatus == FT_STATE_COMPLETE) + { std::string path; path = info.path + "/" + info.fname; /* open file with a suitable application */ QFileInfo qinfo; qinfo.setFile(QString::fromUtf8(path.c_str())); - if (qinfo.exists()) { - if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) { - RsCollection collection; - if (collection.load(qinfo.absoluteFilePath(), false)) { - collection.autoDownloadFiles(); - } - } - } + RsCollection::RsCollectionErrorCode err; + + if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) + RsCollection(qinfo.absoluteFilePath(),err).autoDownloadFiles(); } } } diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 6e377f70e..f87c72760 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -1143,11 +1143,13 @@ QString RetroShareLink::toHtmlSize() const if (type() == TYPE_FILE && RsCollection::isCollectionFile(name())) { FileInfo finfo; - if (rsFiles->FileDetails(RsFileHash(hash().toStdString()), RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, finfo)) { - RsCollection collection; - if (collection.load(QString::fromUtf8(finfo.path.c_str()), false)) { + if (rsFiles->FileDetails(RsFileHash(hash().toStdString()), RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, finfo)) + { + RsCollection::RsCollectionErrorCode code; + RsCollection collection(QString::fromUtf8(finfo.path.c_str()), code) ; + + if(code == RsCollection::RsCollectionErrorCode::NO_ERROR) size += QString(" [%1]").arg(misc::friendlyUnit(collection.size())); - } } } QString link = QString("%2 %3").arg(toString()).arg(name()).arg(size); diff --git a/retroshare-gui/src/gui/common/RsCollection.cpp b/retroshare-gui/src/gui/common/RsCollection.cpp index 1baaed636..08474fb19 100644 --- a/retroshare-gui/src/gui/common/RsCollection.cpp +++ b/retroshare-gui/src/gui/common/RsCollection.cpp @@ -330,97 +330,128 @@ static void showErrorBox(const QString& fileName, const QString& error) mb.exec(); } -bool RsCollection::load(const QString& fileName, bool showError /* = true*/) +QString RsCollection::errorString(RsCollectionErrorCode code) { + switch(code) + { + default: [[fallthrough]] ; + case RsCollectionErrorCode::UNKNOWN_ERROR: return tr("Unknown error"); + case RsCollectionErrorCode::NO_ERROR: return tr("No error"); + case RsCollectionErrorCode::FILE_READ_ERROR: return tr("Error while openning file"); + case RsCollectionErrorCode::FILE_CONTAINS_HARMFUL_STRINGS: return tr("Collection file contains potentially harmful code"); + case RsCollectionErrorCode::INVALID_ROOT_NODE: return tr("Invalid root node. RsCollection node was expected."); + case RsCollectionErrorCode::XML_PARSING_ERROR: return tr("XML parsing error in collection file"); + } +} - if (!checkFile(fileName,showError)) return false; - QFile file(fileName); +RsCollection::RsCollection(const QString& fileName, RsCollectionErrorCode& error) +{ + if (!checkFile(fileName,error)) + return ; - if (!file.open(QIODevice::ReadOnly)) - { - std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl; - if (showError) { - showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName)); - } - return false; - } + QFile file(fileName); + + if (!file.open(QIODevice::ReadOnly)) + { + std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl; + error = RsCollectionErrorCode::FILE_READ_ERROR; + //showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName)); + return ; + } QDomDocument xml_doc; bool ok = xml_doc.setContent(&file) ; - file.close(); + if(!ok) + { + error = RsCollectionErrorCode::XML_PARSING_ERROR; + return; + } + file.close(); + QDomNode root = xml_doc.elementsByTagName("RsCollection").at(0).toElement(); - return ok; + if(root.isNull()) + { + error = RsCollectionErrorCode::INVALID_ROOT_NODE; + return; + } + + recursParseXml(xml_doc,root,0); + error = RsCollectionErrorCode::NO_ERROR; } - // check that the file is a valid rscollection file, and not a lol bomb or some shit like this -bool RsCollection::checkFile(const QString& fileName, bool showError) +// check that the file is a valid rscollection file, and not a lol bomb or some shit like this + +bool RsCollection::checkFile(const QString& fileName, RsCollectionErrorCode& error) { - QFile file(fileName); + QFile file(fileName); + error = RsCollectionErrorCode::NO_ERROR; - if (!file.open(QIODevice::ReadOnly)) - { - std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl; - if (showError) { - showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName)); - } - return false; - } - if (file.reset()){ - std::cerr << "Checking this file for bomb elements and various wrong stuff" << std::endl; - char c ; + if (!file.open(QIODevice::ReadOnly)) + { + std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl; + error = RsCollectionErrorCode::FILE_READ_ERROR; - std::vector bad_strings ; - bad_strings.push_back(std::string("= 0) - { - if (!file.atEnd()) - file.getChar(&c); - else - c=0; + std::vector bad_strings ; + bad_strings.push_back(std::string("= 0) + { + if (!file.atEnd()) + file.getChar(&c); + else + c=0; - if (n == max_size || file.atEnd()) - for(int i=0;i= 'A' && c <= 'Z') c += 'a' - 'A' ; + if(n == max_size) + --n ; - if(!file.atEnd()) - current[n] = c ; - else - current[n] = 0 ; + if(c >= 'A' && c <= 'Z') c += 'a' - 'A' ; - //std::cerr << "n==" << n <<" Checking string " << std::string(current,n+1) << " c = " << std::hex << (int)c << std::dec << std::endl; + if(!file.atEnd()) + current[n] = c ; + else + current[n] = 0 ; - for(uint i=0;i& file_entries, FileSearchFlags flags, QObject *parent = 0) ; RsCollection(const RsFileTree& ft); - virtual ~RsCollection() ; + RsCollection(const QString& filename,RsCollectionErrorCode& error_code); + + static QString errorString(RsCollectionErrorCode code); + + virtual ~RsCollection() ; void merge_in(const QString& fname,uint64_t size,const RsFileHash& hash) ; void merge_in(const RsFileTree& tree) ; @@ -74,9 +86,6 @@ public: bool load(QWidget *parent); bool save(QWidget *parent) const ; #endif - // Loads file from disk. - bool load(const QString& fileName, bool showError = true); - // Save to disk bool save(const QString& fileName) const ; @@ -100,7 +109,7 @@ private slots: private: bool recursExportToXml(QDomDocument& doc,QDomElement& e,const RsFileTree::DirData& dd) const; - bool recursParseXml(QDomDocument& doc,const QDomElement& e,RsFileTree::DirIndex dd) ; + bool recursParseXml(QDomDocument& doc, const QDomNode &e, RsFileTree::DirIndex dd) ; // This function is used to populate a RsCollection from locally or remotly shared files. void recursAddElements(RsFileTree::DirIndex parent, const DirDetails& dd, FileSearchFlags flags) ; @@ -118,7 +127,8 @@ private: #endif // check that the file is a valid rscollection file, and not a lol bomb or some shit like this - static bool checkFile(const QString &fileName, bool showError); + static bool checkFile(const QString &fileName, RsCollectionErrorCode &error); + // Auto Download recursively. void autoDownloadFiles(ColFileInfo colFileInfo, QString dlDir) const ;