Skip to content

Commit

Permalink
Fix calling multiple ZlibDecompressor in parallel causes adler32 chec…
Browse files Browse the repository at this point in the history
…ksum failure (GH weidai11#596, weidai11#600)
  • Loading branch information
rocksonhead authored and noloader committed Mar 25, 2018
1 parent b42d728 commit b0f7170
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 29 deletions.
60 changes: 35 additions & 25 deletions zinflate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,41 +612,51 @@ void Inflator::FlushOutput()
}
}

struct NewFixedLiteralDecoder
void Inflator::CreateFixedLiteralDecoder()
{
HuffmanDecoder * operator()() const
{
unsigned int codeLengths[288];
std::fill(codeLengths + 0, codeLengths + 144, 8);
std::fill(codeLengths + 144, codeLengths + 256, 9);
std::fill(codeLengths + 256, codeLengths + 280, 7);
std::fill(codeLengths + 280, codeLengths + 288, 8);
member_ptr<HuffmanDecoder> pDecoder(new HuffmanDecoder);
pDecoder->Initialize(codeLengths, 288);
return pDecoder.release();
}
unsigned int codeLengths[288];
std::fill(codeLengths + 0, codeLengths + 144, 8);
std::fill(codeLengths + 144, codeLengths + 256, 9);
std::fill(codeLengths + 256, codeLengths + 280, 7);
std::fill(codeLengths + 280, codeLengths + 288, 8);
m_fixedLiteralDecoder.reset(new HuffmanDecoder);
m_fixedLiteralDecoder->Initialize(codeLengths, 288);
};

struct NewFixedDistanceDecoder
void Inflator::CreateFixedDistanceDecoder()
{
HuffmanDecoder * operator()() const
{
unsigned int codeLengths[32];
std::fill(codeLengths + 0, codeLengths + 32, 5);
member_ptr<HuffmanDecoder> pDecoder(new HuffmanDecoder);
pDecoder->Initialize(codeLengths, 32);
return pDecoder.release();
}
unsigned int codeLengths[32];
std::fill(codeLengths + 0, codeLengths + 32, 5);
m_fixedDistanceDecoder.reset(new HuffmanDecoder);
m_fixedDistanceDecoder->Initialize(codeLengths, 32);
};

const HuffmanDecoder& Inflator::GetLiteralDecoder() const
const HuffmanDecoder& Inflator::GetLiteralDecoder()
{
return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedLiteralDecoder>().Ref() : m_dynamicLiteralDecoder;
if (m_blockType == 1)
{
if (m_fixedLiteralDecoder.get() == NULLPTR)
CreateFixedLiteralDecoder();
return *m_fixedLiteralDecoder;
}
else
{
return m_dynamicLiteralDecoder;
}
}

const HuffmanDecoder& Inflator::GetDistanceDecoder() const
const HuffmanDecoder& Inflator::GetDistanceDecoder()
{
return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedDistanceDecoder>().Ref() : m_dynamicDistanceDecoder;
if (m_blockType == 1)
{
if (m_fixedDistanceDecoder.get() == NULLPTR)
CreateFixedDistanceDecoder();
return *m_fixedDistanceDecoder;
}
else
{
return m_dynamicDistanceDecoder;
}
}

NAMESPACE_END
9 changes: 5 additions & 4 deletions zinflate.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ class Inflator : public AutoSignaling<Filter>
void OutputString(const byte *string, size_t length);
void OutputPast(unsigned int length, unsigned int distance);

static const HuffmanDecoder *FixedLiteralDecoder();
static const HuffmanDecoder *FixedDistanceDecoder();
void CreateFixedDistanceDecoder();
void CreateFixedLiteralDecoder();

const HuffmanDecoder& GetLiteralDecoder() const;
const HuffmanDecoder& GetDistanceDecoder() const;
const HuffmanDecoder& GetLiteralDecoder();
const HuffmanDecoder& GetDistanceDecoder();

enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
State m_state;
Expand All @@ -148,6 +148,7 @@ class Inflator : public AutoSignaling<Filter>
NextDecode m_nextDecode;
unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS
HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
member_ptr<HuffmanDecoder> m_fixedLiteralDecoder, m_fixedDistanceDecoder;
LowFirstBitReader m_reader;
SecByteBlock m_window;
size_t m_current, m_lastFlush;
Expand Down

0 comments on commit b0f7170

Please sign in to comment.