Security Scol plugin
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
14NAMESPACE_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
25inline 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
39inline 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
46inline void LowFirstBitReader::SkipBits(unsigned int length)
47{
48 CRYPTOPP_ASSERT(m_bitsBuffered >= length);
49 m_buffer >>= length;
50 m_bitsBuffered -= length;
51}
52
53inline unsigned long LowFirstBitReader::GetBits(unsigned int length)
54{
55 unsigned long result = PeekBits(length);
56 SkipBits(length);
57 return result;
58}
59
60inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, unsigned int codeBits)
61{
62 return code << (MAX_CODE_BITS - codeBits);
63}
64
65void 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
156void 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
183inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const
184{
185 CRYPTOPP_ASSERT(((int)(code & m_cacheMask)) < (int)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
210bool 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
224Inflator::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
241void 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
253void 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
272void 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
301size_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
317bool 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
329void 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:
369 return;
370 }
371 }
372}
373
374void 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
381 switch (m_blockType)
382 {
383 case 0: // stored
384 {
385 m_reader.SkipBits(m_reader.BitsBuffered() % 8);
386 if (!m_reader.FillBuffer(32))
387 throw UnexpectedEndErr();
388 m_storedLen = (word16)m_reader.GetBits(16);
389 word16 nlen = (word16)m_reader.GetBits(16);
390 if (nlen != (word16)~m_storedLen)
391 throw BadBlockErr();
392 break;
393 }
394 case 1: // fixed codes
395 m_nextDecode = LITERAL;
396 break;
397 case 2: // dynamic codes
398 {
399 if (!m_reader.FillBuffer(5+5+4))
400 throw UnexpectedEndErr();
401 unsigned int hlit = m_reader.GetBits(5);
402 unsigned int hdist = m_reader.GetBits(5);
403 unsigned int hclen = m_reader.GetBits(4);
404 unsigned int i = 0;
405
407 static const unsigned int border[] = { // Order of the bit length code lengths
408 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
409 std::fill(codeLengths.begin(), codeLengths+19, 0);
410 for (i=0; i<hclen+4; ++i)
411 {
412 CRYPTOPP_ASSERT(border[i] < codeLengths.size());
413 codeLengths[border[i]] = m_reader.GetBits(3);
414 }
415
416 try
417 {
418 bool result = false;
419 unsigned int k=0, count=0, repeater=0;
420 HuffmanDecoder codeLengthDecoder(codeLengths, 19);
421 for (i=0; i < hlit+257+hdist+1; )
422 {
423 k = 0, count = 0, repeater = 0;
424 result = codeLengthDecoder.Decode(m_reader, k);
425 if (!result)
426 throw UnexpectedEndErr();
427 if (k <= 15)
428 {
429 count = 1;
430 repeater = k;
431 }
432 else switch (k)
433 {
434 case 16:
435 if (!m_reader.FillBuffer(2))
436 throw UnexpectedEndErr();
437 count = 3 + m_reader.GetBits(2);
438 if (i == 0)
439 throw BadBlockErr();
440 repeater = codeLengths[i-1];
441 break;
442 case 17:
443 if (!m_reader.FillBuffer(3))
444 throw UnexpectedEndErr();
445 count = 3 + m_reader.GetBits(3);
446 repeater = 0;
447 break;
448 case 18:
449 if (!m_reader.FillBuffer(7))
450 throw UnexpectedEndErr();
451 count = 11 + m_reader.GetBits(7);
452 repeater = 0;
453 break;
454 }
455 if (i + count > hlit+257+hdist+1)
456 throw BadBlockErr();
457 std::fill(codeLengths + i, codeLengths + i + count, repeater);
458 i += count;
459 }
460 m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257);
461 if (hdist == 0 && codeLengths[hlit+257] == 0)
462 {
463 if (hlit != 0) // a single zero distance code length means all literals
464 throw BadBlockErr();
465 }
466 else
467 m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1);
468 m_nextDecode = LITERAL;
469 }
470 catch (HuffmanDecoder::Err &)
471 {
472 throw BadBlockErr();
473 }
474 break;
475 }
476 default:
477 throw BadBlockErr(); // reserved block type
478 }
479 m_state = DECODING_BODY;
480}
481
482bool Inflator::DecodeBody()
483{
484 bool blockEnd = false;
485 switch (m_blockType)
486 {
487 case 0: // stored
488 CRYPTOPP_ASSERT(m_reader.BitsBuffered() == 0);
489 while (!m_inQueue.IsEmpty() && !blockEnd)
490 {
491 size_t size;
492 const byte *block = m_inQueue.Spy(size);
493 size = UnsignedMin(m_storedLen, size);
494 CRYPTOPP_ASSERT(size <= 0xffff);
495
496 OutputString(block, size);
497 m_inQueue.Skip(size);
498 m_storedLen = m_storedLen - (word16)size;
499 if (m_storedLen == 0)
500 blockEnd = true;
501 }
502 break;
503 case 1: // fixed codes
504 case 2: // dynamic codes
505 static const unsigned int lengthStarts[] = {
506 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
507 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
508 static const unsigned int lengthExtraBits[] = {
509 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
510 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
511 static const unsigned int distanceStarts[] = {
512 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
513 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
514 8193, 12289, 16385, 24577};
515 static const unsigned int distanceExtraBits[] = {
516 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
517 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
518 12, 12, 13, 13};
519
520 const HuffmanDecoder& literalDecoder = GetLiteralDecoder();
521 const HuffmanDecoder& distanceDecoder = GetDistanceDecoder();
522
523 switch (m_nextDecode)
524 {
525 case LITERAL:
526 while (true)
527 {
528 if (!literalDecoder.Decode(m_reader, m_literal))
529 {
530 m_nextDecode = LITERAL;
531 break;
532 }
533 if (m_literal < 256)
534 OutputByte((byte)m_literal);
535 else if (m_literal == 256) // end of block
536 {
537 blockEnd = true;
538 break;
539 }
540 else
541 {
542 if (m_literal > 285)
543 throw BadBlockErr();
544 unsigned int bits;
545 case LENGTH_BITS:
546 CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthExtraBits));
547 bits = lengthExtraBits[m_literal-257];
548 if (!m_reader.FillBuffer(bits))
549 {
550 m_nextDecode = LENGTH_BITS;
551 break;
552 }
553 CRYPTOPP_ASSERT(m_literal-257 < COUNTOF(lengthStarts));
554 m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
555 case DISTANCE:
556 if (!distanceDecoder.Decode(m_reader, m_distance))
557 {
558 m_nextDecode = DISTANCE;
559 break;
560 }
561 case DISTANCE_BITS:
562 CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits));
563 if (m_distance >= COUNTOF(distanceExtraBits))
564 throw BadDistanceErr();
565 bits = distanceExtraBits[m_distance];
566 if (!m_reader.FillBuffer(bits))
567 {
568 m_nextDecode = DISTANCE_BITS;
569 break;
570 }
571 CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts));
572 if (m_distance >= COUNTOF(distanceStarts))
573 throw BadDistanceErr();
574 m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
575 OutputPast(m_literal, m_distance);
576 }
577 }
578 break;
579 default:
580 CRYPTOPP_ASSERT(0);
581 }
582 }
583 if (blockEnd)
584 {
585 if (m_eof)
586 {
587 FlushOutput();
588 m_reader.SkipBits(m_reader.BitsBuffered()%8);
589 if (m_reader.BitsBuffered())
590 {
591 // undo too much lookahead
592 SecBlockWithHint<byte, 4> buffer(m_reader.BitsBuffered() / 8);
593 for (unsigned int i=0; i<buffer.size(); i++)
594 buffer[i] = (byte)m_reader.GetBits(8);
595 m_inQueue.Unget(buffer, buffer.size());
596 }
597 m_state = POST_STREAM;
598 }
599 else
600 m_state = WAIT_HEADER;
601 }
602 return blockEnd;
603}
604
605void Inflator::FlushOutput()
606{
607 if (m_state != PRE_STREAM)
608 {
609 CRYPTOPP_ASSERT(m_current >= m_lastFlush);
610 ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush);
611 m_lastFlush = m_current;
612 }
613}
614
615void Inflator::CreateFixedLiteralDecoder()
616{
617 unsigned int codeLengths[288];
618 std::fill(codeLengths + 0, codeLengths + 144, 8);
619 std::fill(codeLengths + 144, codeLengths + 256, 9);
620 std::fill(codeLengths + 256, codeLengths + 280, 7);
621 std::fill(codeLengths + 280, codeLengths + 288, 8);
622 m_fixedLiteralDecoder.reset(new HuffmanDecoder);
623 m_fixedLiteralDecoder->Initialize(codeLengths, 288);
624}
625
626void Inflator::CreateFixedDistanceDecoder()
627{
628 unsigned int codeLengths[32];
629 std::fill(codeLengths + 0, codeLengths + 32, 5);
630 m_fixedDistanceDecoder.reset(new HuffmanDecoder);
631 m_fixedDistanceDecoder->Initialize(codeLengths, 32);
632}
633
634const HuffmanDecoder& Inflator::GetLiteralDecoder()
635{
636 if (m_blockType == 1)
637 {
638 if (m_fixedLiteralDecoder.get() == NULLPTR)
639 CreateFixedLiteralDecoder();
640 return *m_fixedLiteralDecoder;
641 }
642 else
643 {
644 return m_dynamicLiteralDecoder;
645 }
646}
647
648const HuffmanDecoder& Inflator::GetDistanceDecoder()
649{
650 if (m_blockType == 1)
651 {
652 if (m_fixedDistanceDecoder.get() == NULLPTR)
653 CreateFixedDistanceDecoder();
654 return *m_fixedDistanceDecoder;
655 }
656 else
657 {
658 return m_dynamicDistanceDecoder;
659 }
660}
661
662NAMESPACE_END
Provides auto signaling support.
Definition simple.h:423
int GetAutoSignalPropagation() const
Retrieve automatic signal propagation value.
Definition simple.h:439
Interface for buffered transformations.
Definition cryptlib.h:1652
virtual lword Skip(lword skipMax=LWORD_MAX)
Discard skipMax bytes from the output buffer.
Definition cryptlib.cpp:574
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
Definition cryptlib.cpp:528
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:1991
lword CurrentSize() const
Determine data size.
Definition queue.cpp:200
void Clear()
Empty the queue.
Definition queue.cpp:215
void Unget(byte inByte)
Insert data in the queue.
Definition queue.cpp:400
bool IsEmpty() const
Determine data availability.
Definition queue.cpp:210
const byte * Spy(size_t &contiguousSize) const
Peek data in the queue.
Definition queue.cpp:424
Implementation of BufferedTransformation's attachment interface.
Definition filters.h:36
void Detach(BufferedTransformation *newAttachment=NULLPTR)
Replace an attached transformation.
Definition filters.cpp:50
size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL)
Forward processed data on to attached transformation.
Definition filters.cpp:127
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
Definition filters.cpp:36
Fixed size stack-based SecBlock.
Definition secblock.h:1246
Huffman Decoder.
Definition zinflate.h:40
Exception thrown when a truncated stream is encountered.
Definition zinflate.h:104
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition zinflate.cpp:233
Inflator(BufferedTransformation *attachment=NULLPTR, bool repeat=false, int autoSignalPropagation=-1)
RFC 1951 Decompressor.
Definition zinflate.cpp:224
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition zinflate.cpp:301
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
Definition zinflate.cpp:317
Helper class to finalize Puts on ByteQueue.
Definition queue.h:219
Interface for retrieving values given their names.
Definition cryptlib.h:322
bool GetValue(const char *name, T &value) const
Get a named value.
Definition cryptlib.h:379
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition secblock.h:836
void New(size_type newSize)
Change size without preserving contents.
Definition secblock.h:1126
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
Stack-based SecBlock that grows into the heap.
Definition secblock.h:1268
unsigned char byte
8-bit unsigned datatype
Definition config_int.h:56
unsigned short word16
16-bit unsigned datatype
Definition config_int.h:59
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
Definition misc.h:2110
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition misc.h:655
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:938
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Definition misc.h:694
Precompiled header file.
Classes and functions for secure memory allocations.
Classes for automatic resource management.
Exception thrown by objects that have not implemented nonblocking input processing.
Definition cryptlib.h:1784
DEFLATE compression and decompression (RFC 1951)