Add FileName, FileTime and Comment to argnames.h

Add self tests to verify handling of filenames, filetimes and comments
This commit is contained in:
Jeffrey Walton 2017-05-12 19:52:42 -04:00
parent e3ae7000ea
commit 78db20d939
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
4 changed files with 72 additions and 10 deletions

View File

@ -88,6 +88,9 @@ CRYPTOPP_DEFINE_NAME_STRING(Salt) //!< ConstByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(Tweak) //!< ConstByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(SaltSize) //!< int, in bytes
CRYPTOPP_DEFINE_NAME_STRING(TreeMode) //< byte
CRYPTOPP_DEFINE_NAME_STRING(FileName) //!< const char *
CRYPTOPP_DEFINE_NAME_STRING(FileTime) //!< int
CRYPTOPP_DEFINE_NAME_STRING(Comment) //!< const char *
DOCUMENTED_NAMESPACE_END
NAMESPACE_END

View File

@ -2,6 +2,7 @@
#include "pch.h"
#include "gzip.h"
#include "argnames.h"
NAMESPACE_BEGIN(CryptoPP)
@ -11,6 +12,16 @@ static inline bool Is8859Character(char c) {
return (cc >= 32 && cc <= 126) || (cc >= 160 && cc <= 255);
}
void Gzip::IsolatedInitialize(const NameValuePairs &parameters)
{
ConstByteArrayParameter v;
if (parameters.GetValue(Name::FileName(), v))
m_filename.assign(reinterpret_cast<const char*>(v.begin()), v.size());
if (parameters.GetValue(Name::Comment(), v))
m_comment.assign(reinterpret_cast<const char*>(v.begin()), v.size());
m_filetime = parameters.GetIntValueWithDefault(Name::FileTime(), 0);
}
void Gzip::WritePrestreamHeader()
{
m_totalLen = 0;

10
gzip.h
View File

@ -27,13 +27,17 @@ public:
//! if a file has both compressible and uncompressible parts, it may fail to compress
//! some of the compressible parts.
Gzip(BufferedTransformation *attachment=NULLPTR, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true)
: Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible), m_totalLen(0) {}
: Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible), m_totalLen(0) { }
//! \brief Construct a Gzip compressor
//! \param parameters a set of NameValuePairs to initialize this object
//! \param attachment an attached transformation
//! \details Possible parameter names: Log2WindowSize, DeflateLevel, DetectUncompressible
Gzip(const NameValuePairs &parameters, BufferedTransformation *attachment=NULLPTR)
: Deflator(parameters, attachment), m_totalLen(0) {}
: Deflator(parameters, attachment), m_totalLen(0)
{
IsolatedInitialize(parameters);
}
//! \param filetime the filetime to set in the header. The application is responsible for setting it.
void SetFiletime(word32 filetime) { m_filetime = filetime; }
@ -52,6 +56,8 @@ public:
//! is thrown. If throwOnEncodingError is false then the comment is not checked.
void SetComment(const std::string& comment, bool throwOnEncodingError = false);
void IsolatedInitialize(const NameValuePairs &parameters);
protected:
enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header
DEFLATED=8, FAST=4, SLOW=2};

View File

@ -172,7 +172,7 @@ bool TestCompressors()
// Tamper
try {
StringSource(dest.substr(0, len - 2), true, new Gunzip(new StringSink(rec)));
std::cout << "FAILED: Gzip failed to detect a truncated stream\n";
std::cout << "FAILED: Gzip failed to detect a truncated stream\n";
fail1 = true;
}
catch (const Exception&) {}
@ -186,6 +186,42 @@ bool TestCompressors()
// **************************************************************
// Gzip Filename, Filetime and Comment
try
{
std::string filename = "test.txt";
std::string comment = "This is a test";
word32 filetime = GlobalRNG().GenerateWord32(0, 0xffffff);
AlgorithmParameters params = MakeParameters(Name::FileTime(), (int)filetime)
(Name::FileName(), ConstByteArrayParameter(filename.c_str(), false))
(Name::Comment(), ConstByteArrayParameter(comment.c_str(), false));
std::string src, dest;
unsigned int len = GlobalRNG().GenerateWord32(0, 0xfff);
src.resize(len);
GlobalRNG().GenerateBlock(reinterpret_cast<byte*>(&src[0]), src.size());
Gunzip unzip(new StringSink(dest));
StringSource(src, true, new Gzip(params, new Redirector(unzip)));
if (filename != unzip.GetFilename())
throw Exception(Exception::OTHER_ERROR, "Failed to retrieve filename");
if (filetime != unzip.GetFiletime())
throw Exception(Exception::OTHER_ERROR, "Failed to retrieve filetime");
if (comment != unzip.GetComment())
throw Exception(Exception::OTHER_ERROR, "Failed to retrieve comment");
std::cout << "passed: filenames, filetimes and comments\n";
}
catch (const Exception& ex)
{
std::cout << "FAILED: " << ex.what() << "\n";
}
// Unzip random data. See if we can induce a crash
for (unsigned int i = 0; i<128; i++)
{
@ -213,11 +249,17 @@ bool TestCompressors()
src[2] = 0x00; // extra flags
src[3] = src[3] & (2 | 4 | 8 | 16 | 32); // flags
// Don't allow ENCRYPTED|CONTINUED to over-run tests
if (src[3] & (2 | 32)) {
if (i % 3 == 0) { src[3] &= ~2; }
if (i % 3 == 1) { src[3] &= ~32; }
}
// Commit d901ecd9a4de added Filenames, Filetimes and Comments. Gzip does
// not specify a length for them; rather, they are NULL terminated. We add
// a couple of NULLs in random places near filenames and comments to ensure
// we are getting coverage in areas beyond the header.
len = GlobalRNG().GenerateWord32(12, 24);
if (len < src.size()) // guard it to ensure in-bounds
src[len] = (byte)0x00;
len = GlobalRNG().GenerateWord32(12+len, 24+len);
if (len < src.size()) // guard it to ensure in-bounds
src[len] = (byte)0x00;
// The remainder are extra headers and the payload
try {
@ -252,7 +294,7 @@ bool TestCompressors()
// Tamper
try {
StringSource(dest.substr(0, len - 2), true, new Gunzip(new StringSink(rec)));
std::cout << "FAILED: Inflate failed to detect a truncated stream\n";
std::cout << "FAILED: Inflate failed to detect a truncated stream\n";
fail2 = true;
}
catch (const Exception&) {}
@ -333,7 +375,7 @@ bool TestCompressors()
// Tamper
try {
StringSource(dest.substr(0, len - 2), true, new Gunzip(new StringSink(rec)));
std::cout << "FAILED: Zlib failed to detect a truncated stream\n";
std::cout << "FAILED: Zlib failed to detect a truncated stream\n";
fail3 = true;
}
catch (const Exception&) {}