Skip to content

Commit db756a7

Browse files
authored
Don't allow to sign empty file (#623)
IB-8195 Signed-off-by: Raul Metsma <[email protected]>
1 parent 1c99e5d commit db756a7

File tree

2 files changed

+27
-44
lines changed

2 files changed

+27
-44
lines changed

src/ASiContainer.cpp

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,10 @@
2121

2222
#include "DataFile_p.h"
2323
#include "Signature.h"
24-
#include "util/DateTime.h"
2524
#include "util/File.h"
2625
#include "util/log.h"
27-
#include "util/ZipSerialize.h"
2826

2927
#include <algorithm>
30-
#include <array>
3128
#include <ctime>
3229
#include <fstream>
3330
#include <map>
@@ -48,29 +45,24 @@ class ASiContainer::Private
4845
map<string, ZipSerialize::Properties> properties;
4946
};
5047

51-
const string ASiContainer::MIMETYPE_ASIC_E = "application/vnd.etsi.asic-e+zip";
52-
const string ASiContainer::MIMETYPE_ASIC_S = "application/vnd.etsi.asic-s+zip";
53-
//https://signa.mitsoft.lt/static/signa-web/webResources/docs/ADOC_specification_approved20090907_EN.pdf
54-
const string ASiContainer::MIMETYPE_ADOC = "application/vnd.lt.archyvai.adoc-2008";
55-
5648
/**
57-
* Initialize BDOC container.
49+
* Initialize Container.
5850
*/
59-
ASiContainer::ASiContainer(const string &mimetype)
51+
ASiContainer::ASiContainer(string_view mimetype)
6052
: d(make_unique<Private>())
6153
{
6254
d->mimetype = mimetype;
6355
}
6456

6557
/**
66-
* Loads ASi Container from a file.
58+
* Loads Container from a file.
6759
*
6860
* @param path name of the container file.
6961
* @param mimetypeRequired flag indicating if the mimetype must be present and checked.
7062
* @param supported supported mimetypes.
7163
* @return returns zip serializer for the container.
7264
*/
73-
unique_ptr<ZipSerialize> ASiContainer::load(const string &path, bool mimetypeRequired, const set<string> &supported)
65+
unique_ptr<ZipSerialize> ASiContainer::load(const string &path, bool mimetypeRequired, const set<string_view> &supported)
7466
{
7567
DEBUG("ASiContainer::ASiContainer(path = '%s')", path.c_str());
7668
auto z = make_unique<ZipSerialize>(d->path = path, false);
@@ -79,17 +71,17 @@ unique_ptr<ZipSerialize> ASiContainer::load(const string &path, bool mimetypeReq
7971
if(list.empty())
8072
THROW("Failed to parse container");
8173

74+
// ETSI TS 102 918: mimetype has to be the first in the archive
8275
if(mimetypeRequired && list.front() != "mimetype")
8376
THROW("required mimetype not found");
8477

85-
// ETSI TS 102 918: mimetype has to be the first in the archive
8678
if(list.front() == "mimetype")
8779
{
8880
d->mimetype = readMimetype(*z);
89-
DEBUG("mimetype = '%s'", d->mimetype.c_str());
9081
if(supported.find(d->mimetype) == supported.cend())
9182
THROW("Incorrect mimetype '%s'", d->mimetype.c_str());
9283
}
84+
DEBUG("mimetype = '%s'", d->mimetype.c_str());
9385

9486
for(const string &file: list)
9587
d->properties[file] = z->properties(file);
@@ -167,24 +159,20 @@ void ASiContainer::addDataFile(const string &path, const string &mediaType)
167159
{
168160
string fileName = File::fileName(path);
169161
addDataFileChecks(fileName, mediaType);
170-
if(!File::fileExists(path))
171-
THROW("Document file '%s' does not exist.", path.c_str());
172-
173-
ZipSerialize::Properties prop { appInfo(), File::modifiedTime(path), File::fileSize(path) };
174-
bool useTempFile = prop.size > MAX_MEM_FILE;
175-
zproperty(fileName, std::move(prop));
176-
unique_ptr<istream> is;
177-
if(useTempFile)
178-
{
179-
is = make_unique<ifstream>(File::encodeName(path), ifstream::binary);
180-
}
181-
else
162+
auto size = File::fileSize(path);
163+
if(size == 0)
164+
THROW("Document file '%s' does not exist or is empty.", path.c_str());
165+
166+
unique_ptr<istream> is = make_unique<ifstream>(File::encodeName(path), ifstream::binary);
167+
if(!*is)
168+
THROW("Failed to open file for reading: %s.", path.c_str());
169+
if(size <= MAX_MEM_FILE)
182170
{
183171
auto data = make_unique<stringstream>();
184-
if(ifstream file{File::encodeName(path), ifstream::binary})
185-
*data << file.rdbuf();
172+
*data << is->rdbuf();
186173
is = std::move(data);
187174
}
175+
d->properties[fileName] = { appInfo(), File::modifiedTime(path), size };
188176
addDataFilePrivate(std::move(is), std::move(fileName), mediaType);
189177
}
190178

@@ -270,18 +258,13 @@ string ASiContainer::zpath() const
270258
return d->path;
271259
}
272260

273-
ZipSerialize::Properties ASiContainer::zproperty(const string &file) const
261+
const ZipSerialize::Properties& ASiContainer::zproperty(const string &file) const
274262
{
275263
if(auto i = d->properties.find(file); i != d->properties.cend())
276264
return i->second;
277265
return d->properties[file] = { appInfo(), time(nullptr), 0 };
278266
}
279267

280-
void ASiContainer::zproperty(const string &file, ZipSerialize::Properties &&prop)
281-
{
282-
d->properties[file] = std::move(prop);
283-
}
284-
285268
/**
286269
* Reads and parses container mimetype. Checks that the mimetype is supported.
287270
*
@@ -294,9 +277,9 @@ string ASiContainer::readMimetype(const ZipSerialize &z)
294277
DEBUG("ASiContainer::readMimetype()");
295278
stringstream is;
296279
z.extract("mimetype", is);
297-
string text;
298-
is >> text;
299-
if(!is)
280+
string text = is.str();
281+
text.erase(text.find_last_not_of(" \n\r\f\t\v") + 1);
282+
if(text.empty())
300283
THROW("Failed to read mimetype.");
301284
// Contains UTF-16 BOM
302285
if(text.find("\xFF\xEF") == 0 || text.find("\xEF\xFF") == 0)

src/ASiContainer.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ namespace digidoc
3838
class ASiContainer: public Container
3939
{
4040
public:
41-
static const std::string MIMETYPE_ASIC_E;
42-
static const std::string MIMETYPE_ASIC_S;
43-
static const std::string MIMETYPE_ADOC;
41+
static constexpr std::string_view MIMETYPE_ASIC_E = "application/vnd.etsi.asic-e+zip";
42+
static constexpr std::string_view MIMETYPE_ASIC_S = "application/vnd.etsi.asic-s+zip";
43+
//https://signa.mitsoft.lt/static/signa-web/webResources/docs/ADOC_specification_approved20090907_EN.pdf
44+
static constexpr std::string_view MIMETYPE_ADOC = "application/vnd.lt.archyvai.adoc-2008";
4445

4546
~ASiContainer() override;
4647
std::string mediaType() const override;
@@ -55,18 +56,17 @@ namespace digidoc
5556
static std::string readMimetype(const ZipSerialize &z);
5657

5758
protected:
58-
ASiContainer(const std::string &mimetype);
59+
ASiContainer(std::string_view mimetype);
5960

6061
void addDataFilePrivate(std::unique_ptr<std::istream> is, std::string fileName, std::string mediaType);
6162
Signature* addSignature(std::unique_ptr<Signature> &&signature);
6263
std::unique_ptr<std::iostream> dataStream(const std::string &path, const ZipSerialize &z) const;
63-
std::unique_ptr<ZipSerialize> load(const std::string &path, bool requireMimetype, const std::set<std::string> &supported);
64+
std::unique_ptr<ZipSerialize> load(const std::string &path, bool requireMimetype, const std::set<std::string_view> &supported);
6465
void deleteSignature(Signature* s);
6566

6667
void zpath(const std::string &file);
6768
std::string zpath() const;
68-
ZipSerialize::Properties zproperty(const std::string &file) const;
69-
void zproperty(const std::string &file, ZipSerialize::Properties &&prop);
69+
const ZipSerialize::Properties &zproperty(const std::string &file) const;
7070

7171
private:
7272
DISABLE_COPY(ASiContainer);

0 commit comments

Comments
 (0)