Crypto++  5.6.5
Free C++ class library of cryptographic schemes
zinflate.cpp
1 // zinflate.cpp - originally written and placed in the public domain by Wei Dai
2 
3 // This is a complete reimplementation of the DEFLATE decompression algorithm.
4 // It should not be affected by any security vulnerabilities in the zlib
5 // compression library. In particular it is not affected by the double free bug
6 // (http://www.kb.cert.org/vuls/id/368819).
7 
8 #include "pch.h"
9 
10 #include "zinflate.h"
11 #include "secblock.h"
12 #include "smartptr.h"
13 
14 NAMESPACE_BEGIN(CryptoPP)
15 
17 {
18  inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
19  {return lhs < rhs.code;}
20  // needed for MSVC .NET 2005
21  inline bool operator()(const CryptoPP::HuffmanDecoder::CodeInfo &lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs)
22  {return lhs.code < rhs.code;}
23 };
24 
25 inline bool LowFirstBitReader::FillBuffer(unsigned int length)
26 {
27  while (m_bitsBuffered < length)
28  {
29  byte b;
30  if (!m_store.Get(b))
31  return false;
32  m_buffer |= (unsigned long)b << m_bitsBuffered;
33  m_bitsBuffered += 8;
34  }
35  CRYPTOPP_ASSERT(m_bitsBuffered <= sizeof(unsigned long)*8);
36  return true;
37 }
38 
39 inline unsigned long LowFirstBitReader::PeekBits(unsigned int length)
40 {
41  bool result = FillBuffer(length);
42  CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result);
43  return m_buffer & (((unsigned long)1 << length) - 1);
44 }
45 
46 inline void LowFirstBitReader::SkipBits(unsigned int length)
47 {
48  CRYPTOPP_ASSERT(m_bitsBuffered >= length);
49  m_buffer >>= length;
50  m_bitsBuffered -= length;
51 }
52 
53 inline unsigned long LowFirstBitReader::GetBits(unsigned int length)
54 {
55  unsigned long result = PeekBits(length);
56  SkipBits(length);
57  return result;
58 }
59 
60 inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, unsigned int codeBits)
61 {
62  return code << (MAX_CODE_BITS - codeBits);
63 }
64 
65 void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes)
66 {
67  // the Huffman codes are represented in 3 ways in this code:
68  //
69  // 1. most significant code bit (i.e. top of code tree) in the least significant bit position
70  // 2. most significant code bit (i.e. top of code tree) in the most significant bit position
71  // 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position,
72  // where n is the maximum code length for this code tree
73  //
74  // (1) is the way the codes come in from the deflate stream
75  // (2) is used to sort codes so they can be binary searched
76  // (3) is used in this function to compute codes from code lengths
77  //
78  // a code in representation (2) is called "normalized" here
79  // The BitReverse() function is used to convert between (1) and (2)
80  // The NormalizeCode() function is used to convert from (3) to (2)
81 
82  if (nCodes == 0)
83  throw Err("null code");
84 
85  m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);
86 
87  if (m_maxCodeBits > MAX_CODE_BITS)
88  throw Err("code length exceeds maximum");
89 
90  if (m_maxCodeBits == 0)
91  throw Err("null code");
92 
93  // count number of codes of each length
94  SecBlockWithHint<unsigned int, 15+1> blCount(m_maxCodeBits+1);
95  std::fill(blCount.begin(), blCount.end(), 0);
96  unsigned int i;
97  for (i=0; i<nCodes; i++)
98  blCount[codeBits[i]]++;
99 
100  // compute the starting code of each length
101  code_t code = 0;
102  SecBlockWithHint<code_t, 15+1> nextCode(m_maxCodeBits+1);
103  nextCode[1] = 0;
104  for (i=2; i<=m_maxCodeBits; i++)
105  {
106  // compute this while checking for overflow: code = (code + blCount[i-1]) << 1
107  if (code > code + blCount[i-1])
108  throw Err("codes oversubscribed");
109  code += blCount[i-1];
110  if (code > (code << 1))
111  throw Err("codes oversubscribed");
112  code <<= 1;
113  nextCode[i] = code;
114  }
115 
116  // MAX_CODE_BITS is 32, m_maxCodeBits may be smaller.
117  const word64 shiftedMaxCode = ((word64)1 << m_maxCodeBits);
118  if (code > shiftedMaxCode - blCount[m_maxCodeBits])
119  throw Err("codes oversubscribed");
120  else if (m_maxCodeBits != 1 && code < shiftedMaxCode - blCount[m_maxCodeBits])
121  throw Err("codes incomplete");
122 
123  // compute a vector of <code, length, value> triples sorted by code
124  m_codeToValue.resize(nCodes - blCount[0]);
125  unsigned int j=0;
126  for (i=0; i<nCodes; i++)
127  {
128  unsigned int len = codeBits[i];
129  if (len != 0)
130  {
131  CRYPTOPP_ASSERT(j < m_codeToValue.size());
132  code = NormalizeCode(nextCode[len]++, len);
133  m_codeToValue[j].code = code;
134  m_codeToValue[j].len = len;
135  m_codeToValue[j].value = i;
136  j++;
137  }
138  }
139  std::sort(m_codeToValue.begin(), m_codeToValue.end());
140 
141  // initialize the decoding cache
142  m_cacheBits = STDMIN(9U, m_maxCodeBits);
143  m_cacheMask = (1 << m_cacheBits) - 1;
144  m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
145  CRYPTOPP_ASSERT(m_normalizedCacheMask == BitReverse(m_cacheMask));
146 
147  const word64 shiftedCache = ((word64)1 << m_cacheBits);
148  CRYPTOPP_ASSERT(shiftedCache <= SIZE_MAX);
149  if (m_cache.size() != shiftedCache)
150  m_cache.resize((size_t)shiftedCache);
151 
152  for (i=0; i<m_cache.size(); i++)
153  m_cache[i].type = 0;
154 }
155 
156 void HuffmanDecoder::FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const
157 {
158  normalizedCode &= m_normalizedCacheMask;
159  const CodeInfo &codeInfo = *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode, CodeLessThan())-1);
160  if (codeInfo.len <= m_cacheBits)
161  {
162  entry.type = 1;
163  entry.value = codeInfo.value;
164  entry.len = codeInfo.len;
165  }
166  else
167  {
168  entry.begin = &codeInfo;
169  const CodeInfo *last = & *(std::upper_bound(m_codeToValue.begin(), m_codeToValue.end(), normalizedCode + ~m_normalizedCacheMask, CodeLessThan())-1);
170  if (codeInfo.len == last->len)
171  {
172  entry.type = 2;
173  entry.len = codeInfo.len;
174  }
175  else
176  {
177  entry.type = 3;
178  entry.end = last+1;
179  }
180  }
181 }
182 
183 inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const
184 {
185  CRYPTOPP_ASSERT(((int)(code & m_cacheMask)) < m_cache.size());
186  LookupEntry &entry = m_cache[code & m_cacheMask];
187 
188  code_t normalizedCode = 0;
189  if (entry.type != 1)
190  normalizedCode = BitReverse(code);
191 
192  if (entry.type == 0)
193  FillCacheEntry(entry, normalizedCode);
194 
195  if (entry.type == 1)
196  {
197  value = entry.value;
198  return entry.len;
199  }
200  else
201  {
202  const CodeInfo &codeInfo = (entry.type == 2)
203  ? entry.begin[(normalizedCode << m_cacheBits) >> (MAX_CODE_BITS - (entry.len - m_cacheBits))]
204  : *(std::upper_bound(entry.begin, entry.end, normalizedCode, CodeLessThan())-1);
205  value = codeInfo.value;
206  return codeInfo.len;
207  }
208 }
209 
210 bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const
211 {
212  bool result = reader.FillBuffer(m_maxCodeBits);
213  CRYPTOPP_UNUSED(result); // CRYPTOPP_ASSERT(result);
214 
215  unsigned int codeBits = Decode(reader.PeekBuffer(), value);
216  if (codeBits > reader.BitsBuffered())
217  return false;
218  reader.SkipBits(codeBits);
219  return true;
220 }
221 
222 // *************************************************************
223 
224 Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation)
225  : AutoSignaling<Filter>(propagation)
226  , m_state(PRE_STREAM), m_repeat(repeat), m_eof(0), m_wrappedAround(0)
227  , m_blockType(0xff), m_storedLen(0xffff), m_nextDecode(), m_literal(0)
228  , m_distance(0), m_reader(m_inQueue), m_current(0), m_lastFlush(0)
229 {
230  Detach(attachment);
231 }
232 
234 {
235  m_state = PRE_STREAM;
236  parameters.GetValue("Repeat", m_repeat);
237  m_inQueue.Clear();
238  m_reader.SkipBits(m_reader.BitsBuffered());
239 }
240 
241 void Inflator::OutputByte(byte b)
242 {
243  m_window[m_current++] = b;
244  if (m_current == m_window.size())
245  {
246  ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
247  m_lastFlush = 0;
248  m_current = 0;
249  m_wrappedAround = true;
250  }
251 }
252 
253 void Inflator::OutputString(const byte *string, size_t length)
254 {
255  while (length)
256  {
257  size_t len = UnsignedMin(length, m_window.size() - m_current);
258  memcpy(m_window + m_current, string, len);
259  m_current += len;
260  if (m_current == m_window.size())
261  {
262  ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
263  m_lastFlush = 0;
264  m_current = 0;
265  m_wrappedAround = true;
266  }
267  string += len;
268  length -= len;
269  }
270 }
271 
272 void Inflator::OutputPast(unsigned int length, unsigned int distance)
273 {
274  size_t start;
275  if (distance <= m_current)
276  start = m_current - distance;
277  else if (m_wrappedAround && distance <= m_window.size())
278  start = m_current + m_window.size() - distance;
279  else
280  throw BadBlockErr();
281 
282  if (start + length > m_window.size())
283  {
284  for (; start < m_window.size(); start++, length--)
285  OutputByte(m_window[start]);
286  start = 0;
287  }
288 
289  if (start + length > m_current || m_current + length >= m_window.size())
290  {
291  while (length--)
292  OutputByte(m_window[start++]);
293  }
294  else
295  {
296  memcpy(m_window + m_current, m_window + start, length);
297  m_current += length;
298  }
299 }
300 
301 size_t Inflator::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
302 {
303  if (!blocking)
304  throw BlockingInputOnly("Inflator");
305 
306  LazyPutter lp(m_inQueue, inString, length);
307  ProcessInput(messageEnd != 0);
308 
309  if (messageEnd)
310  if (!(m_state == PRE_STREAM || m_state == AFTER_END))
311  throw UnexpectedEndErr();
312 
313  Output(0, NULLPTR, 0, messageEnd, blocking);
314  return 0;
315 }
316 
317 bool Inflator::IsolatedFlush(bool hardFlush, bool blocking)
318 {
319  if (!blocking)
320  throw BlockingInputOnly("Inflator");
321 
322  if (hardFlush)
323  ProcessInput(true);
324  FlushOutput();
325 
326  return false;
327 }
328 
329 void Inflator::ProcessInput(bool flush)
330 {
331  while (true)
332  {
333  switch (m_state)
334  {
335  case PRE_STREAM:
336  if (!flush && m_inQueue.CurrentSize() < MaxPrestreamHeaderSize())
337  return;
338  ProcessPrestreamHeader();
339  m_state = WAIT_HEADER;
340  m_wrappedAround = false;
341  m_current = 0;
342  m_lastFlush = 0;
343  m_window.New(((size_t) 1) << GetLog2WindowSize());
344  break;
345  case WAIT_HEADER:
346  {
347  // maximum number of bytes before actual compressed data starts
348  const size_t MAX_HEADER_SIZE = BitsToBytes(3+5+5+4+19*7+286*15+19*15);
349  if (m_inQueue.CurrentSize() < (flush ? 1 : MAX_HEADER_SIZE))
350  return;
351  DecodeHeader();
352  break;
353  }
354  case DECODING_BODY:
355  if (!DecodeBody())
356  return;
357  break;
358  case POST_STREAM:
359  if (!flush && m_inQueue.CurrentSize() < MaxPoststreamTailSize())
360  return;
361  ProcessPoststreamTail();
362  m_state = m_repeat ? PRE_STREAM : AFTER_END;
363  Output(0, NULLPTR, 0, GetAutoSignalPropagation(), true); // TODO: non-blocking
364  if (m_inQueue.IsEmpty())
365  return;
366  break;
367  case AFTER_END:
368  m_inQueue.TransferTo(*AttachedTransformation());
369  return;
370  }
371  }
372 }
373 
374 void Inflator::DecodeHeader()
375 {
376  if (!m_reader.FillBuffer(3))
377  throw UnexpectedEndErr();
378  m_eof = m_reader.GetBits(1) != 0;
379  m_blockType = (byte)m_reader.GetBits(2);
380  switch (m_blockType)
381  {
382  case 0: // stored
383  {
384  m_reader.SkipBits(m_reader.BitsBuffered() % 8);
385  if (!m_reader.FillBuffer(32))
386  throw UnexpectedEndErr();
387  m_storedLen = (word16)m_reader.GetBits(16);
388  word16 nlen = (word16)m_reader.GetBits(16);
389  if (nlen != (word16)~m_storedLen)
390  throw BadBlockErr();
391  break;
392  }
393  case 1: // fixed codes
394  m_nextDecode = LITERAL;
395  break;
396  case 2: // dynamic codes
397  {
398  if (!m_reader.FillBuffer(5+5+4))
399  throw UnexpectedEndErr();
400  unsigned int hlit = m_reader.GetBits(5);
401  unsigned int hdist = m_reader.GetBits(5);
402  unsigned int hclen = m_reader.GetBits(4);
403 
405  unsigned int i;
406  static const unsigned int border[] = { // Order of the bit length code lengths
407  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
408  std::fill(codeLengths.begin(), codeLengths+19, 0);
409  for (i=0; i<hclen+4; i++)
410  {
411  CRYPTOPP_ASSERT(border[i] < codeLengths.size());
412  codeLengths[border[i]] = m_reader.GetBits(3);
413  }
414 
415  try
416  {
417  HuffmanDecoder codeLengthDecoder(codeLengths, 19);
418  for (i = 0; i < hlit+257+hdist+1; )
419  {
420  unsigned int k = 0, count = 0, repeater = 0;
421  bool result = codeLengthDecoder.Decode(m_reader, k);
422  if (!result)
423  throw UnexpectedEndErr();
424  if (k <= 15)
425  {
426  count = 1;
427  repeater = k;
428  }
429  else switch (k)
430  {
431  case 16:
432  if (!m_reader.FillBuffer(2))
433  throw UnexpectedEndErr();
434  count = 3 + m_reader.GetBits(2);
435  if (i == 0)
436  throw BadBlockErr();
437  repeater = codeLengths[i-1];
438  break;
439  case 17:
440  if (!m_reader.FillBuffer(3))
441  throw UnexpectedEndErr();
442  count = 3 + m_reader.GetBits(3);
443  repeater = 0;
444  break;
445  case 18:
446  if (!m_reader.FillBuffer(7))
447  throw UnexpectedEndErr();
448  count = 11 + m_reader.GetBits(7);
449  repeater = 0;
450  break;
451  }
452  if (i + count > hlit+257+hdist+1)
453  throw BadBlockErr();
454  std::fill(codeLengths + i, codeLengths + i + count, repeater);
455  i += count;
456  }
457  m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257);
458  if (hdist == 0 && codeLengths[hlit+257] == 0)
459  {
460  if (hlit != 0) // a single zero distance code length means all literals
461  throw BadBlockErr();
462  }
463  else
464  m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1);
465  m_nextDecode = LITERAL;
466  }
467  catch (HuffmanDecoder::Err &)
468  {
469  throw BadBlockErr();
470  }
471  break;
472  }
473  default:
474  throw BadBlockErr(); // reserved block type
475  }
476  m_state = DECODING_BODY;
477 }
478 
479 bool Inflator::DecodeBody()
480 {
481  bool blockEnd = false;
482  switch (m_blockType)
483  {
484  case 0: // stored
485  CRYPTOPP_ASSERT(m_reader.BitsBuffered() == 0);
486  while (!m_inQueue.IsEmpty() && !blockEnd)
487  {
488  size_t size;
489  const byte *block = m_inQueue.Spy(size);
490  size = UnsignedMin(m_storedLen, size);
491  CRYPTOPP_ASSERT(size <= 0xffff);
492 
493  OutputString(block, size);
494  m_inQueue.Skip(size);
495  m_storedLen = m_storedLen - (word16)size;
496  if (m_storedLen == 0)
497  blockEnd = true;
498  }
499  break;
500  case 1: // fixed codes
501  case 2: // dynamic codes
502  static const unsigned int lengthStarts[] = {
503  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
504  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
505  static const unsigned int lengthExtraBits[] = {
506  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
507  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
508  static const unsigned int distanceStarts[] = {
509  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
510  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
511  8193, 12289, 16385, 24577};
512  static const unsigned int distanceExtraBits[] = {
513  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
514  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
515  12, 12, 13, 13};
516 
517  const HuffmanDecoder& literalDecoder = GetLiteralDecoder();
518  const HuffmanDecoder& distanceDecoder = GetDistanceDecoder();
519 
520  switch (m_nextDecode)
521  {
522  case LITERAL:
523  while (true)
524  {
525  if (!literalDecoder.Decode(m_reader, m_literal))
526  {
527  m_nextDecode = LITERAL;
528  break;
529  }
530  if (m_literal < 256)
531  OutputByte((byte)m_literal);
532  else if (m_literal == 256) // end of block
533  {
534  blockEnd = true;
535  break;
536  }
537  else
538  {
539  if (m_literal > 285)
540  throw BadBlockErr();
541  unsigned int bits;
542  case LENGTH_BITS:
543  CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthExtraBits));
544  bits = lengthExtraBits[m_literal-257];
545  if (!m_reader.FillBuffer(bits))
546  {
547  m_nextDecode = LENGTH_BITS;
548  break;
549  }
550  CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthStarts));
551  m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
552  case DISTANCE:
553  if (!distanceDecoder.Decode(m_reader, m_distance))
554  {
555  m_nextDecode = DISTANCE;
556  break;
557  }
558  case DISTANCE_BITS:
559  // TODO: this surfaced during fuzzing. What do we do???
560  CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits));
561  if (m_distance >= COUNTOF(distanceExtraBits))
562  throw BadDistanceErr();
563  bits = distanceExtraBits[m_distance];
564  if (!m_reader.FillBuffer(bits))
565  {
566  m_nextDecode = DISTANCE_BITS;
567  break;
568  }
569  // TODO: this surfaced during fuzzing. What do we do???
570  CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts));
571  if (m_distance >= COUNTOF(distanceStarts))
572  throw BadDistanceErr();
573  m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
574  OutputPast(m_literal, m_distance);
575  }
576  }
577  break;
578  default:
579  CRYPTOPP_ASSERT(0);
580  }
581  }
582  if (blockEnd)
583  {
584  if (m_eof)
585  {
586  FlushOutput();
587  m_reader.SkipBits(m_reader.BitsBuffered()%8);
588  if (m_reader.BitsBuffered())
589  {
590  // undo too much lookahead
591  SecBlockWithHint<byte, 4> buffer(m_reader.BitsBuffered() / 8);
592  for (unsigned int i=0; i<buffer.size(); i++)
593  buffer[i] = (byte)m_reader.GetBits(8);
594  m_inQueue.Unget(buffer, buffer.size());
595  }
596  m_state = POST_STREAM;
597  }
598  else
599  m_state = WAIT_HEADER;
600  }
601  return blockEnd;
602 }
603 
604 void Inflator::FlushOutput()
605 {
606  if (m_state != PRE_STREAM)
607  {
608  CRYPTOPP_ASSERT(m_current >= m_lastFlush);
609  ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush);
610  m_lastFlush = m_current;
611  }
612 }
613 
615 {
616  HuffmanDecoder * operator()() const
617  {
618  unsigned int codeLengths[288];
619  std::fill(codeLengths + 0, codeLengths + 144, 8);
620  std::fill(codeLengths + 144, codeLengths + 256, 9);
621  std::fill(codeLengths + 256, codeLengths + 280, 7);
622  std::fill(codeLengths + 280, codeLengths + 288, 8);
624  pDecoder->Initialize(codeLengths, 288);
625  return pDecoder.release();
626  }
627 };
628 
630 {
631  HuffmanDecoder * operator()() const
632  {
633  unsigned int codeLengths[32];
634  std::fill(codeLengths + 0, codeLengths + 32, 5);
636  pDecoder->Initialize(codeLengths, 32);
637  return pDecoder.release();
638  }
639 };
640 
641 const HuffmanDecoder& Inflator::GetLiteralDecoder() const
642 {
643  return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedLiteralDecoder>().Ref() : m_dynamicLiteralDecoder;
644 }
645 
646 const HuffmanDecoder& Inflator::GetDistanceDecoder() const
647 {
648  return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedDistanceDecoder>().Ref() : m_dynamicDistanceDecoder;
649 }
650 
651 NAMESPACE_END
Inflator(BufferedTransformation *attachment=NULL, bool repeat=false, int autoSignalPropagation=-1)
RFC 1951 Decompressor.
Definition: zinflate.cpp:224
iterator end()
Provides an iterator pointing beyond the last element in the memory block.
Definition: secblock.h:553
use this to make sure LazyPut is finalized in event of exception
Definition: queue.h:128
Stack-based SecBlock that grows into the heap.
Definition: secblock.h:855
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:309
Exception thrown when a truncated stream is encountered.
Definition: zinflate.h:102
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition: misc.h:796
Classes for automatic resource management.
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
Definition: zinflate.cpp:317
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:717
Interface for buffered transformations.
Definition: cryptlib.h:1343
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
Definition: misc.h:1845
Pointer that overloads operator ->
Definition: smartptr.h:39
Classes and functions for secure memory allocations.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition: zinflate.cpp:233
lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
move transferMax bytes of the buffered output to target as input
Definition: cryptlib.h:1637
void Detach(BufferedTransformation *newAttachment=NULL)
Replace an attached transformation.
Definition: filters.cpp:50
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
Definition: filters.cpp:36
Exception thrown when an invalid distance is encountered.
Definition: zinflate.h:106
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:552
virtual lword Skip(lword skipMax=LWORD_MAX)
Discard skipMax bytes from the output buffer.
Definition: cryptlib.cpp:525
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:196
Huffman Decoder.
Definition: zinflate.h:36
Fixed size stack-based SecBlock.
Definition: secblock.h:832
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:514
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:545
Exception thrown by objects that have not implemented nonblocking input processing.
Definition: cryptlib.h:1458
Provides auto signaling support.
Definition: simple.h:288
Implementation of BufferedTransformation&#39;s attachment interface.
Definition: filters.h:36
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: zinflate.cpp:301
BufferedTransformation & Ref()
Provides a reference to this object.
Definition: cryptlib.h:1354
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
Definition: cryptlib.cpp:487
Crypto++ library namespace.
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:343
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:570
Exception thrown when a bad block is encountered.
Definition: zinflate.h:104
#define SIZE_MAX
The maximum value of a machine word.
Definition: misc.h:102
Interface for retrieving values given their names.
Definition: cryptlib.h:285