Add Inflator::BadDistanceErr exception (Issue 414)

The improved validation and excpetion clears the Address Sanitizer and Undefined Behavior Sanitizer findings
pull/416/head
Jeffrey Walton 2017-05-10 18:17:12 -04:00
parent e456cd2275
commit 07dbcc3d96
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
3 changed files with 14 additions and 4 deletions

View File

@ -623,7 +623,7 @@ bool TestRandomPool()
std::cout << "FAILED:"; std::cout << "FAILED:";
else else
std::cout << "passed:"; std::cout << "passed:";
std::cout << " GenerateWord32 and Crop\n"; std::cout << " GenerateWord32 and Crop\n";
} }
#if !defined(NO_OS_DEPENDENCE) #if !defined(NO_OS_DEPENDENCE)
@ -711,7 +711,7 @@ bool TestRandomPool()
std::cout << "FAILED:"; std::cout << "FAILED:";
else else
std::cout << "passed:"; std::cout << "passed:";
std::cout << " GenerateWord32 and Crop\n"; std::cout << " GenerateWord32 and Crop\n";
} }
#endif #endif
@ -808,7 +808,7 @@ bool TestAutoSeededX917()
std::cout << "FAILED:"; std::cout << "FAILED:";
else else
std::cout << "passed:"; std::cout << "passed:";
std::cout << " GenerateWord32 and Crop\n"; std::cout << " GenerateWord32 and Crop\n";
std::cout.flush(); std::cout.flush();
return pass; return pass;

View File

@ -552,12 +552,18 @@ bool Inflator::DecodeBody()
case DISTANCE_BITS: case DISTANCE_BITS:
// TODO: this surfaced during fuzzing. What do we do??? // TODO: this surfaced during fuzzing. What do we do???
CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits)); CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits));
bits = (m_distance >= COUNTOF(distanceExtraBits)) ? distanceExtraBits[29] : distanceExtraBits[m_distance]; if (m_distance >= COUNTOF(distanceExtraBits))
throw BadDistanceErr();
bits = distanceExtraBits[m_distance];
if (!m_reader.FillBuffer(bits)) if (!m_reader.FillBuffer(bits))
{ {
m_nextDecode = DISTANCE_BITS; m_nextDecode = DISTANCE_BITS;
break; break;
} }
// TODO: this surfaced during fuzzing. What do we do???
CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts));
if (m_distance >= COUNTOF(distanceStarts))
throw BadDistanceErr();
m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance]; m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
OutputPast(m_literal, m_distance); OutputPast(m_literal, m_distance);
} }

View File

@ -98,8 +98,12 @@ public:
Err(ErrorType e, const std::string &s) Err(ErrorType e, const std::string &s)
: Exception(e, s) {} : Exception(e, s) {}
}; };
//! \brief Exception thrown when a truncated stream is encountered
class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}}; class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
//! \brief Exception thrown when a bad block is encountered
class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}}; class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
//! \brief Exception thrown when an invalid distance is encountered
class BadDistanceErr : public Err {public: BadDistanceErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in bit distance") {}};
//! \brief RFC 1951 Decompressor //! \brief RFC 1951 Decompressor
//! \param attachment the filter's attached transformation //! \param attachment the filter's attached transformation