diff options
author | Jeffrey Walton <noloader@gmail.com> | 2017-05-10 20:32:50 -0400 |
---|---|---|
committer | Jeffrey Walton <noloader@gmail.com> | 2017-05-10 20:32:50 -0400 |
commit | 2a20d09dc61ec1ae0cb6d95210e2c00ebee3f4c3 (patch) | |
tree | 4886fd1f77e0a7151566df8cfc33f8bdb7211c4b | |
parent | 07dbcc3d9644b18e05c1776db2a57fe04d780965 (diff) | |
download | cryptopp-git-2a20d09dc61ec1ae0cb6d95210e2c00ebee3f4c3.tar.gz |
Additional self tests for Decompressors
-rw-r--r-- | validat0.cpp | 26 | ||||
-rw-r--r-- | zinflate.cpp | 8 |
2 files changed, 33 insertions, 1 deletions
diff --git a/validat0.cpp b/validat0.cpp index 7277203a..f4837d56 100644 --- a/validat0.cpp +++ b/validat0.cpp @@ -2281,6 +2281,32 @@ bool TestHuffmanCodes() std::cout << "passed:";
std::cout << " GenerateCodeLengths" << std::endl;
+ // Try to crash the HuffmanDecoder
+ for (unsigned int i=0; i<128; ++i)
+ {
+ try
+ {
+ byte data1[0xfff]; // Place on stack, avoid new
+ unsigned int data2[0xff];
+
+ unsigned int len1 = GlobalRNG().GenerateWord32(0, 0xfff);
+ GlobalRNG().GenerateBlock(data1, len1);
+ unsigned int len2 = GlobalRNG().GenerateWord32(0, 0xff);
+ GlobalRNG().GenerateBlock((byte*)data2, len2*sizeof(unsigned int));
+
+ ArraySource source(data1, len1, false);
+ HuffmanDecoder decoder(data2, len2);
+
+ LowFirstBitReader reader(source);
+ unsigned int val;
+ for (unsigned int j=0; !source.AnyRetrievable(); ++j)
+ decoder.Decode(reader, val);
+ }
+ catch (const Exception&) {}
+ }
+
+ std::cout << "passed: HuffmanDecoder decode" << std::endl;
+
return pass;
}
#endif
diff --git a/zinflate.cpp b/zinflate.cpp index ee15c945..41690ef9 100644 --- a/zinflate.cpp +++ b/zinflate.cpp @@ -128,6 +128,7 @@ void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCode unsigned int len = codeBits[i];
if (len != 0)
{
+ CRYPTOPP_ASSERT(j < m_codeToValue.size());
code = NormalizeCode(nextCode[len]++, len);
m_codeToValue[j].code = code;
m_codeToValue[j].len = len;
@@ -181,7 +182,7 @@ void HuffmanDecoder::FillCacheEntry(LookupEntry &entry, code_t normalizedCode) c inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const
{
- CRYPTOPP_ASSERT(m_codeToValue.size() > 0);
+ CRYPTOPP_ASSERT(((int)(code & m_cacheMask)) < m_cache.size());
LookupEntry &entry = m_cache[code & m_cacheMask];
code_t normalizedCode = 0;
@@ -406,7 +407,10 @@ void Inflator::DecodeHeader() 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
std::fill(codeLengths.begin(), codeLengths+19, 0);
for (i=0; i<hclen+4; i++)
+ {
+ CRYPTOPP_ASSERT(border[i] < codeLengths.size());
codeLengths[border[i]] = m_reader.GetBits(3);
+ }
try
{
@@ -536,12 +540,14 @@ bool Inflator::DecodeBody() throw BadBlockErr();
unsigned int bits;
case LENGTH_BITS:
+ CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthExtraBits));
bits = lengthExtraBits[m_literal-257];
if (!m_reader.FillBuffer(bits))
{
m_nextDecode = LENGTH_BITS;
break;
}
+ CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthStarts));
m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
case DISTANCE:
if (!distanceDecoder.Decode(m_reader, m_distance))
|