diff --git a/src/ASiC_E.cpp b/src/ASiC_E.cpp index a2cc90fd6..5ac894e2c 100644 --- a/src/ASiC_E.cpp +++ b/src/ASiC_E.cpp @@ -192,6 +192,8 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z) mimeFound = true; continue; } + if(full_path.empty()) + THROW("Manifest file entry full-path is empty."); if(full_path.back() == '/') // Skip Directory entries continue; @@ -201,7 +203,7 @@ void ASiC_E::parseManifestAndLoadFiles(const ZipSerialize &z) full_path.starts_with("metadata/"))) d->metadata.push_back(new DataFilePrivate(z, string(full_path), string(media_type))); else - addDataFilePrivate(new DataFilePrivate(z, string(full_path), string(media_type))); + addDataFilePrivate(z, full_path, media_type); } if(!mimeFound) THROW("Manifest is missing mediatype file entry."); diff --git a/src/ASiC_S.cpp b/src/ASiC_S.cpp index 9ba56669a..dcf7b5575 100644 --- a/src/ASiC_S.cpp +++ b/src/ASiC_S.cpp @@ -19,7 +19,6 @@ #include "ASiC_S.h" -#include "DataFile_p.h" #include "SignatureTST.h" #include "SignatureXAdES_LTA.h" #include "crypto/Signer.h" @@ -78,10 +77,7 @@ ASiC_S::ASiC_S(const string &path) else if(!dataFiles().empty()) THROW("Can not add document to ASiC-S container which already contains a document."); else - { - addDataFileChecks(file, "application/octet-stream"); - addDataFilePrivate(new DataFilePrivate(z, file, "application/octet-stream")); - } + addDataFilePrivate(z, file, "application/octet-stream"); } if(foundTimestamp && !foundManifest) { diff --git a/src/ASiContainer.cpp b/src/ASiContainer.cpp index d143b709d..1f13d1b77 100644 --- a/src/ASiContainer.cpp +++ b/src/ASiContainer.cpp @@ -172,26 +172,33 @@ void ASiContainer::addDataFile(const string &path, const string &mediaType) void ASiContainer::addDataFile(unique_ptr is, const string &fileName, const string &mediaType) { addDataFileChecks(fileName, mediaType); - if(fileName.find_last_of("/\\") != string::npos) - THROW("Document file '%s' cannot contain directory path.", fileName.c_str()); d->documents.push_back(new DataFilePrivate(std::move(is), fileName, mediaType)); } +void ASiContainer::validateDataFileName(string_view fileName) +{ + if(fileName.empty() || fileName == "." || fileName == ".." || + fileName.find_first_of("/\\") != string_view::npos) + THROW("Document file '%.*s' cannot contain directory path.", STR_VIEW_FMT(fileName)); +} + void ASiContainer::addDataFileChecks(const string &fileName, const string &mediaType) { if(!d->signatures.empty()) THROW("Can not add document to container which has signatures, remove all signatures before adding new document."); if(fileName == "mimetype") THROW("mimetype is reserved file."); + validateDataFileName(fileName); if(any_of(d->documents.cbegin(), d->documents.cend(), [&](DataFile *file) { return fileName == file->fileName(); })) THROW("Document with same file name '%s' already exists.", fileName.c_str()); if(mediaType.find('/') == string::npos) THROW("MediaType does not meet format requirements (RFC2045, section 5.1) '%s'.", mediaType.c_str()); } -void ASiContainer::addDataFilePrivate(DataFile *dataFile) +void ASiContainer::addDataFilePrivate(const ZipSerialize &z, string_view filename, string_view mediatype) { - d->documents.push_back(dataFile); + validateDataFileName(filename); + d->documents.push_back(new DataFilePrivate(z, string(filename), string(mediatype))); } /** diff --git a/src/ASiContainer.h b/src/ASiContainer.h index f6c40fe89..d8a907945 100644 --- a/src/ASiContainer.h +++ b/src/ASiContainer.h @@ -62,13 +62,14 @@ namespace digidoc ASiContainer(std::string_view mimetype); virtual void addDataFileChecks(const std::string &path, const std::string &mediaType); - void addDataFilePrivate(DataFile *dataFile); + void addDataFilePrivate(const ZipSerialize &z, std::string_view filename, std::string_view mediatype); Signature* addSignature(std::unique_ptr &&signature); virtual void canSave() = 0; XMLDocument createManifest() const; ZipSerialize load(const std::string &path, bool requireMimetype, const std::set &supported); virtual void save(const ZipSerialize &s) = 0; void deleteSignature(Signature* s); + static void validateDataFileName(std::string_view fileName); void zpath(const std::string &file); std::string zpath() const;