File indexing completed on 2025-01-18 09:29:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef BOOST_BEAST_ZLIB_DETAIL_INFLATE_STREAM_IPP
0038 #define BOOST_BEAST_ZLIB_DETAIL_INFLATE_STREAM_IPP
0039
0040 #include <boost/beast/zlib/detail/inflate_stream.hpp>
0041 #include <boost/throw_exception.hpp>
0042 #include <array>
0043
0044 namespace boost {
0045 namespace beast {
0046 namespace zlib {
0047 namespace detail {
0048
0049 void
0050 inflate_stream::
0051 doClear()
0052 {
0053 }
0054
0055 void
0056 inflate_stream::
0057 doReset(int windowBits)
0058 {
0059 if(windowBits < 8 || windowBits > 15)
0060 BOOST_THROW_EXCEPTION(std::domain_error{
0061 "windowBits out of range"});
0062 w_.reset(windowBits);
0063
0064 bi_.flush();
0065 mode_ = HEAD;
0066 last_ = 0;
0067 dmax_ = 32768U;
0068 lencode_ = codes_;
0069 distcode_ = codes_;
0070 next_ = codes_;
0071 back_ = -1;
0072 }
0073
0074 void
0075 inflate_stream::
0076 doWrite(z_params& zs, Flush flush, error_code& ec)
0077 {
0078 ranges r;
0079 r.in.first = static_cast<
0080 std::uint8_t const*>(zs.next_in);
0081 r.in.last = r.in.first + zs.avail_in;
0082 r.in.next = r.in.first;
0083 r.out.first = static_cast<
0084 std::uint8_t*>(zs.next_out);
0085 r.out.last = r.out.first + zs.avail_out;
0086 r.out.next = r.out.first;
0087
0088 auto const done =
0089 [&]
0090 {
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 if( (r.out.used() && mode_ < BAD &&
0101 (mode_ < CHECK || flush != Flush::finish)))
0102 w_.write(r.out.first, r.out.used());
0103
0104 zs.next_in = r.in.next;
0105 zs.avail_in = r.in.avail();
0106 zs.next_out = r.out.next;
0107 zs.avail_out = r.out.avail();
0108 zs.total_in += r.in.used();
0109 zs.total_out += r.out.used();
0110 zs.data_type = bi_.size() + (last_ ? 64 : 0) +
0111 (mode_ == TYPE ? 128 : 0) +
0112 (mode_ == LEN_ || mode_ == COPY_ ? 256 : 0);
0113
0114 if(((! r.in.used() && ! r.out.used()) ||
0115 flush == Flush::finish) && ! ec)
0116 {
0117 BOOST_BEAST_ASSIGN_EC(ec, error::need_buffers);
0118 }
0119 };
0120 auto const err =
0121 [&](error e)
0122 {
0123 BOOST_BEAST_ASSIGN_EC(ec, e);
0124 mode_ = BAD;
0125 };
0126
0127 if(mode_ == TYPE)
0128 mode_ = TYPEDO;
0129
0130 for(;;)
0131 {
0132 switch(mode_)
0133 {
0134 case HEAD:
0135 mode_ = TYPEDO;
0136 break;
0137
0138 case TYPE:
0139 if(flush == Flush::block || flush == Flush::trees)
0140 return done();
0141
0142
0143 case TYPEDO:
0144 {
0145 if(last_)
0146 {
0147 bi_.flush_byte();
0148 mode_ = CHECK;
0149 break;
0150 }
0151 if(! bi_.fill(3, r.in.next, r.in.last))
0152 return done();
0153 std::uint8_t v;
0154 bi_.read(v, 1);
0155 last_ = v != 0;
0156 bi_.read(v, 2);
0157 switch(v)
0158 {
0159 case 0:
0160
0161 mode_ = STORED;
0162 break;
0163 case 1:
0164
0165 fixedTables();
0166 mode_ = LEN_;
0167 if(flush == Flush::trees)
0168 return done();
0169 break;
0170 case 2:
0171
0172 mode_ = TABLE;
0173 break;
0174
0175 default:
0176 return err(error::invalid_block_type);
0177 }
0178 break;
0179 }
0180
0181 case STORED:
0182 {
0183 bi_.flush_byte();
0184 std::uint32_t v;
0185 if(! bi_.fill(32, r.in.next, r.in.last))
0186 return done();
0187 bi_.peek(v, 32);
0188 length_ = v & 0xffff;
0189 if(length_ != ((v >> 16) ^ 0xffff))
0190 return err(error::invalid_stored_length);
0191
0192
0193 bi_.flush();
0194 mode_ = COPY_;
0195 if(flush == Flush::trees)
0196 return done();
0197 BOOST_FALLTHROUGH;
0198 }
0199
0200 case COPY_:
0201 mode_ = COPY;
0202 BOOST_FALLTHROUGH;
0203
0204 case COPY:
0205 {
0206 auto copy = length_;
0207 if(copy == 0)
0208 {
0209 mode_ = TYPE;
0210 break;
0211 }
0212 copy = clamp(copy, r.in.avail());
0213 copy = clamp(copy, r.out.avail());
0214 if(copy == 0)
0215 return done();
0216 std::memcpy(r.out.next, r.in.next, copy);
0217 r.in.next += copy;
0218 r.out.next += copy;
0219 length_ -= copy;
0220 break;
0221 }
0222
0223 case TABLE:
0224 if(! bi_.fill(5 + 5 + 4, r.in.next, r.in.last))
0225 return done();
0226 bi_.read(nlen_, 5);
0227 nlen_ += 257;
0228 bi_.read(ndist_, 5);
0229 ndist_ += 1;
0230 bi_.read(ncode_, 4);
0231 ncode_ += 4;
0232 if(nlen_ > 286 || ndist_ > 30)
0233 return err(error::too_many_symbols);
0234 have_ = 0;
0235 mode_ = LENLENS;
0236 BOOST_FALLTHROUGH;
0237
0238 case LENLENS:
0239 {
0240 static std::array<std::uint8_t, 19> constexpr order = {{
0241 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}};
0242 while(have_ < ncode_)
0243 {
0244 if(! bi_.fill(3, r.in.next, r.in.last))
0245 return done();
0246 bi_.read(lens_[order[have_]], 3);
0247 ++have_;
0248 }
0249 while(have_ < order.size())
0250 lens_[order[have_++]] = 0;
0251
0252 next_ = &codes_[0];
0253 lencode_ = next_;
0254 lenbits_ = 7;
0255 inflate_table(build::codes, &lens_[0],
0256 order.size(), &next_, &lenbits_, work_, ec);
0257 if(ec)
0258 {
0259 mode_ = BAD;
0260 break;
0261 }
0262 have_ = 0;
0263 mode_ = CODELENS;
0264 BOOST_FALLTHROUGH;
0265 }
0266
0267 case CODELENS:
0268 {
0269 while(have_ < nlen_ + ndist_)
0270 {
0271 std::uint16_t v;
0272 if(! bi_.fill(lenbits_, r.in.next, r.in.last))
0273 return done();
0274 bi_.peek(v, lenbits_);
0275 auto cp = &lencode_[v];
0276 if(cp->val < 16)
0277 {
0278 bi_.drop(cp->bits);
0279 lens_[have_++] = cp->val;
0280 }
0281 else
0282 {
0283 std::uint16_t len;
0284 std::uint16_t copy;
0285 if(cp->val == 16)
0286 {
0287 if(! bi_.fill(cp->bits + 2, r.in.next, r.in.last))
0288 return done();
0289 bi_.drop(cp->bits);
0290 if(have_ == 0)
0291 return err(error::invalid_bit_length_repeat);
0292 bi_.read(copy, 2);
0293 len = lens_[have_ - 1];
0294 copy += 3;
0295
0296 }
0297 else if(cp->val == 17)
0298 {
0299 if(! bi_.fill(cp->bits + 3, r.in.next, r.in.last))
0300 return done();
0301 bi_.drop(cp->bits);
0302 bi_.read(copy, 3);
0303 len = 0;
0304 copy += 3;
0305 }
0306 else
0307 {
0308 if(! bi_.fill(cp->bits + 7, r.in.next, r.in.last))
0309 return done();
0310 bi_.drop(cp->bits);
0311 bi_.read(copy, 7);
0312 len = 0;
0313 copy += 11;
0314 }
0315 if(have_ + copy > nlen_ + ndist_)
0316 return err(error::invalid_bit_length_repeat);
0317 std::fill(&lens_[have_], &lens_[have_ + copy], len);
0318 have_ += copy;
0319 copy = 0;
0320 }
0321 }
0322
0323 if(mode_ == BAD)
0324 break;
0325
0326 if(lens_[256] == 0)
0327 return err(error::missing_eob);
0328
0329
0330
0331 next_ = &codes_[0];
0332 lencode_ = next_;
0333 lenbits_ = 9;
0334 inflate_table(build::lens, &lens_[0],
0335 nlen_, &next_, &lenbits_, work_, ec);
0336 if(ec)
0337 {
0338 mode_ = BAD;
0339 return;
0340 }
0341 distcode_ = next_;
0342 distbits_ = 6;
0343 inflate_table(build::dists, lens_ + nlen_,
0344 ndist_, &next_, &distbits_, work_, ec);
0345 if(ec)
0346 {
0347 mode_ = BAD;
0348 return;
0349 }
0350 mode_ = LEN_;
0351 if(flush == Flush::trees)
0352 return done();
0353 BOOST_FALLTHROUGH;
0354 }
0355
0356 case LEN_:
0357 mode_ = LEN;
0358 BOOST_FALLTHROUGH;
0359
0360 case LEN:
0361 {
0362 if(r.in.avail() >= 6 && r.out.avail() >= 258)
0363 {
0364 inflate_fast(r, ec);
0365 if(ec)
0366 {
0367 mode_ = BAD;
0368 return;
0369 }
0370 if(mode_ == TYPE)
0371 back_ = -1;
0372 break;
0373 }
0374 if(! bi_.fill(lenbits_, r.in.next, r.in.last))
0375 return done();
0376 std::uint16_t v;
0377 back_ = 0;
0378 bi_.peek(v, lenbits_);
0379 auto cp = &lencode_[v];
0380 if(cp->op && (cp->op & 0xf0) == 0)
0381 {
0382 auto prev = cp;
0383 if(! bi_.fill(prev->bits + prev->op, r.in.next, r.in.last))
0384 return done();
0385 bi_.peek(v, prev->bits + prev->op);
0386 cp = &lencode_[prev->val + (v >> prev->bits)];
0387 bi_.drop(prev->bits + cp->bits);
0388 back_ += prev->bits + cp->bits;
0389 }
0390 else
0391 {
0392 bi_.drop(cp->bits);
0393 back_ += cp->bits;
0394 }
0395 length_ = cp->val;
0396 if(cp->op == 0)
0397 {
0398 mode_ = LIT;
0399 break;
0400 }
0401 if(cp->op & 32)
0402 {
0403 back_ = -1;
0404 mode_ = TYPE;
0405 break;
0406 }
0407 if(cp->op & 64)
0408 return err(error::invalid_literal_length);
0409 extra_ = cp->op & 15;
0410 mode_ = LENEXT;
0411 BOOST_FALLTHROUGH;
0412 }
0413
0414 case LENEXT:
0415 if(extra_)
0416 {
0417 if(! bi_.fill(extra_, r.in.next, r.in.last))
0418 return done();
0419 std::uint16_t v;
0420 bi_.read(v, extra_);
0421 length_ += v;
0422 back_ += extra_;
0423 }
0424 was_ = length_;
0425 mode_ = DIST;
0426 BOOST_FALLTHROUGH;
0427
0428 case DIST:
0429 {
0430 if(! bi_.fill(distbits_, r.in.next, r.in.last))
0431 return done();
0432 std::uint16_t v;
0433 bi_.peek(v, distbits_);
0434 auto cp = &distcode_[v];
0435 if((cp->op & 0xf0) == 0)
0436 {
0437 auto prev = cp;
0438 if(! bi_.fill(prev->bits + prev->op, r.in.next, r.in.last))
0439 return done();
0440 bi_.peek(v, prev->bits + prev->op);
0441 cp = &distcode_[prev->val + (v >> prev->bits)];
0442 bi_.drop(prev->bits + cp->bits);
0443 back_ += prev->bits + cp->bits;
0444 }
0445 else
0446 {
0447 bi_.drop(cp->bits);
0448 back_ += cp->bits;
0449 }
0450 if(cp->op & 64)
0451 return err(error::invalid_distance_code);
0452 offset_ = cp->val;
0453 extra_ = cp->op & 15;
0454 mode_ = DISTEXT;
0455 BOOST_FALLTHROUGH;
0456 }
0457
0458 case DISTEXT:
0459 if(extra_)
0460 {
0461 std::uint16_t v;
0462 if(! bi_.fill(extra_, r.in.next, r.in.last))
0463 return done();
0464 bi_.read(v, extra_);
0465 offset_ += v;
0466 back_ += extra_;
0467 }
0468 #ifdef INFLATE_STRICT
0469 if(offset_ > dmax_)
0470 return err(error::invalid_distance);
0471 #endif
0472 mode_ = MATCH;
0473 BOOST_FALLTHROUGH;
0474
0475 case MATCH:
0476 {
0477 if(! r.out.avail())
0478 return done();
0479 if(offset_ > r.out.used())
0480 {
0481
0482 auto offset = static_cast<std::uint16_t>(
0483 offset_ - r.out.used());
0484 if(offset > w_.size())
0485 return err(error::invalid_distance);
0486 auto const n = clamp(clamp(
0487 length_, offset), r.out.avail());
0488 w_.read(r.out.next, offset, n);
0489 r.out.next += n;
0490 length_ -= n;
0491 }
0492 else
0493 {
0494
0495 auto in = r.out.next - offset_;
0496 auto n = clamp(length_, r.out.avail());
0497 length_ -= n;
0498 while(n--)
0499 *r.out.next++ = *in++;
0500 }
0501 if(length_ == 0)
0502 mode_ = LEN;
0503 break;
0504 }
0505
0506 case LIT:
0507 {
0508 if(! r.out.avail())
0509 return done();
0510 auto const v = static_cast<std::uint8_t>(length_);
0511 *r.out.next++ = v;
0512 mode_ = LEN;
0513 break;
0514 }
0515
0516 case CHECK:
0517 mode_ = DONE;
0518 BOOST_FALLTHROUGH;
0519
0520 case DONE:
0521 {
0522 BOOST_BEAST_ASSIGN_EC(ec, error::end_of_stream);
0523 return done();
0524 }
0525
0526 case BAD:
0527 return done();
0528
0529 case SYNC:
0530 default:
0531 BOOST_THROW_EXCEPTION(std::logic_error{
0532 "stream error"});
0533 }
0534 }
0535 }
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551 void
0552 inflate_stream::
0553 inflate_table(
0554 build type,
0555 std::uint16_t* lens,
0556 std::size_t codes,
0557 code** table,
0558 unsigned *bits,
0559 std::uint16_t* work,
0560 error_code& ec)
0561 {
0562 unsigned len;
0563 unsigned sym;
0564 unsigned min, max;
0565 unsigned root;
0566 unsigned curr;
0567 unsigned drop;
0568 int left;
0569 unsigned used;
0570 unsigned huff;
0571 unsigned incr;
0572 unsigned fill;
0573 unsigned low;
0574 unsigned mask;
0575 code here;
0576 code *next;
0577 std::uint16_t const* base;
0578 std::uint16_t const* extra;
0579 unsigned match;
0580 std::uint16_t count[15+1];
0581 std::uint16_t offs[15+1];
0582
0583
0584 static std::uint16_t constexpr lbase[31] = {
0585 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
0586 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
0587
0588
0589 static std::uint16_t constexpr lext[31] = {
0590 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
0591 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
0592
0593
0594 static std::uint16_t constexpr dbase[32] = {
0595 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
0596 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
0597 8193, 12289, 16385, 24577, 0, 0};
0598
0599
0600 static std::uint16_t constexpr dext[32] = {
0601 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
0602 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
0603 28, 28, 29, 29, 64, 64};
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637 for (len = 0; len <= 15; len++)
0638 count[len] = 0;
0639 for (sym = 0; sym < codes; sym++)
0640 count[lens[sym]]++;
0641
0642
0643 root = *bits;
0644 for (max = 15; max >= 1; max--)
0645 if (count[max] != 0)
0646 break;
0647 if (root > max)
0648 root = max;
0649 if (max == 0)
0650 {
0651 here.op = (std::uint8_t)64;
0652 here.bits = (std::uint8_t)1;
0653 here.val = (std::uint16_t)0;
0654 *(*table)++ = here;
0655 *(*table)++ = here;
0656 *bits = 1;
0657 return;
0658 }
0659 for (min = 1; min < max; min++)
0660 if (count[min] != 0)
0661 break;
0662 if (root < min)
0663 root = min;
0664
0665
0666 left = 1;
0667 for (len = 1; len <= 15; len++)
0668 {
0669 left <<= 1;
0670 left -= count[len];
0671 if (left < 0)
0672 {
0673 BOOST_BEAST_ASSIGN_EC(ec, error::over_subscribed_length);
0674 return;
0675 }
0676 }
0677 if (left > 0 && (type == build::codes || max != 1))
0678 {
0679 BOOST_BEAST_ASSIGN_EC(ec, error::incomplete_length_set);
0680 return;
0681 }
0682
0683
0684 offs[1] = 0;
0685 for (len = 1; len < 15; len++)
0686 offs[len + 1] = offs[len] + count[len];
0687
0688
0689 for (sym = 0; sym < codes; sym++)
0690 if (lens[sym] != 0)
0691 work[offs[lens[sym]]++] = (std::uint16_t)sym;
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 switch (type)
0726 {
0727 case build::codes:
0728 base = extra = work;
0729 match = 20;
0730 break;
0731 case build::lens:
0732 base = lbase;
0733 extra = lext;
0734 match = 257;
0735 break;
0736 default:
0737 base = dbase;
0738 extra = dext;
0739 match = 0;
0740 }
0741
0742
0743 huff = 0;
0744 sym = 0;
0745 len = min;
0746 next = *table;
0747 curr = root;
0748 drop = 0;
0749 low = (unsigned)(-1);
0750 used = 1U << root;
0751 mask = used - 1;
0752
0753 auto const not_enough = []
0754 {
0755 BOOST_THROW_EXCEPTION(std::logic_error{
0756 "insufficient output size when inflating tables"});
0757 };
0758
0759
0760 if ((type == build::lens && used > kEnoughLens) ||
0761 (type == build::dists && used > kEnoughDists))
0762 return not_enough();
0763
0764
0765 for (;;)
0766 {
0767
0768 here.bits = (std::uint8_t)(len - drop);
0769 if (work[sym] + 1U < match)
0770 {
0771 here.op = (std::uint8_t)0;
0772 here.val = work[sym];
0773 }
0774 else if (work[sym] >= match)
0775 {
0776 here.op = (std::uint8_t)(extra[work[sym] - match]);
0777 here.val = base[work[sym] - match];
0778 }
0779 else
0780 {
0781 here.op = (std::uint8_t)(32 + 64);
0782 here.val = 0;
0783 }
0784
0785
0786 incr = 1U << (len - drop);
0787 fill = 1U << curr;
0788 min = fill;
0789 do
0790 {
0791 fill -= incr;
0792 next[(huff >> drop) + fill] = here;
0793 } while (fill != 0);
0794
0795
0796 incr = 1U << (len - 1);
0797 while (huff & incr)
0798 incr >>= 1;
0799 if (incr != 0)
0800 {
0801 huff &= incr - 1;
0802 huff += incr;
0803 }
0804 else
0805 huff = 0;
0806
0807
0808 sym++;
0809 if (--(count[len]) == 0)
0810 {
0811 if (len == max) break;
0812 len = lens[work[sym]];
0813 }
0814
0815
0816 if (len > root && (huff & mask) != low)
0817 {
0818
0819 if (drop == 0)
0820 drop = root;
0821
0822
0823 next += min;
0824
0825
0826 curr = len - drop;
0827 left = (int)(1 << curr);
0828 while (curr + drop < max)
0829 {
0830 left -= count[curr + drop];
0831 if (left <= 0) break;
0832 curr++;
0833 left <<= 1;
0834 }
0835
0836
0837 used += 1U << curr;
0838 if ((type == build::lens && used > kEnoughLens) ||
0839 (type == build::dists && used > kEnoughDists))
0840 return not_enough();
0841
0842
0843 low = huff & mask;
0844 (*table)[low].op = (std::uint8_t)curr;
0845 (*table)[low].bits = (std::uint8_t)root;
0846 (*table)[low].val = (std::uint16_t)(next - *table);
0847 }
0848 }
0849
0850
0851
0852
0853 if (huff != 0)
0854 {
0855 here.op = 64;
0856 here.bits = (std::uint8_t)(len - drop);
0857 here.val = 0;
0858 next[huff] = here;
0859 }
0860
0861 *table += used;
0862 *bits = root;
0863 }
0864
0865 auto
0866 inflate_stream::
0867 get_fixed_tables() ->
0868 codes const&
0869 {
0870 struct fixed_codes : codes
0871 {
0872 code len_[512];
0873 code dist_[32];
0874
0875 fixed_codes()
0876 {
0877 lencode = len_;
0878 lenbits = 9;
0879 distcode = dist_;
0880 distbits = 5;
0881
0882 std::uint16_t lens[320];
0883 std::uint16_t work[288];
0884
0885 std::fill(&lens[ 0], &lens[144], std::uint16_t{8});
0886 std::fill(&lens[144], &lens[256], std::uint16_t{9});
0887 std::fill(&lens[256], &lens[280], std::uint16_t{7});
0888 std::fill(&lens[280], &lens[288], std::uint16_t{8});
0889
0890 {
0891 error_code ec;
0892 auto next = &len_[0];
0893 inflate_table(build::lens,
0894 lens, 288, &next, &lenbits, work, ec);
0895 if(ec)
0896 BOOST_THROW_EXCEPTION(std::logic_error{ec.message()});
0897 }
0898
0899
0900 len_[ 99].op = 64;
0901 len_[227].op = 64;
0902 len_[355].op = 64;
0903 len_[483].op = 64;
0904
0905 {
0906 error_code ec;
0907 auto next = &dist_[0];
0908 std::fill(&lens[0], &lens[32], std::uint16_t{5});
0909 inflate_table(build::dists,
0910 lens, 32, &next, &distbits, work, ec);
0911 if(ec)
0912 BOOST_THROW_EXCEPTION(std::logic_error{ec.message()});
0913 }
0914 }
0915 };
0916
0917 static fixed_codes const fc;
0918 return fc;
0919 }
0920
0921 void
0922 inflate_stream::
0923 fixedTables()
0924 {
0925 auto const fc = get_fixed_tables();
0926 lencode_ = fc.lencode;
0927 lenbits_ = fc.lenbits;
0928 distcode_ = fc.distcode;
0929 distbits_ = fc.distbits;
0930 }
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979 void
0980 inflate_stream::
0981 inflate_fast(ranges& r, error_code& ec)
0982 {
0983 unsigned char const* last;
0984 unsigned char *end;
0985 std::size_t op;
0986 unsigned len;
0987 unsigned dist;
0988 unsigned const lmask =
0989 (1U << lenbits_) - 1;
0990 unsigned const dmask =
0991 (1U << distbits_) - 1;
0992
0993 last = r.in.next + (r.in.avail() - 5);
0994 end = r.out.next + (r.out.avail() - 257);
0995
0996
0997
0998 do
0999 {
1000 if(bi_.size() < 15)
1001 bi_.fill_16(r.in.next);
1002 auto cp = &lencode_[bi_.peek_fast() & lmask];
1003 dolen:
1004 bi_.drop(cp->bits);
1005 op = (unsigned)(cp->op);
1006 if(op == 0)
1007 {
1008
1009 *r.out.next++ = (unsigned char)(cp->val);
1010 }
1011 else if(op & 16)
1012 {
1013
1014 len = (unsigned)(cp->val);
1015 op &= 15;
1016 if(op)
1017 {
1018 if(bi_.size() < op)
1019 bi_.fill_8(r.in.next);
1020 len += (unsigned)bi_.peek_fast() & ((1U << op) - 1);
1021 bi_.drop(op);
1022 }
1023 if(bi_.size() < 15)
1024 bi_.fill_16(r.in.next);
1025 cp = &distcode_[bi_.peek_fast() & dmask];
1026 dodist:
1027 bi_.drop(cp->bits);
1028 op = (unsigned)(cp->op);
1029 if(op & 16)
1030 {
1031
1032 dist = (unsigned)(cp->val);
1033 op &= 15;
1034 if(bi_.size() < op)
1035 {
1036 bi_.fill_8(r.in.next);
1037 if(bi_.size() < op)
1038 bi_.fill_8(r.in.next);
1039 }
1040 dist += (unsigned)bi_.peek_fast() & ((1U << op) - 1);
1041 #ifdef INFLATE_STRICT
1042 if(dist > dmax_)
1043 {
1044 BOOST_BEAST_ASSIGN_EC(ec, error::invalid_distance);
1045 mode_ = BAD;
1046 break;
1047 }
1048 #endif
1049 bi_.drop(op);
1050
1051 op = r.out.used();
1052 if(dist > op)
1053 {
1054
1055 op = dist - op;
1056 if(op > w_.size())
1057 {
1058 BOOST_BEAST_ASSIGN_EC(ec, error::invalid_distance);
1059 mode_ = BAD;
1060 break;
1061 }
1062 auto const n = clamp(len, op);
1063 w_.read(r.out.next, op, n);
1064 r.out.next += n;
1065 len -= n;
1066 }
1067 if(len > 0)
1068 {
1069
1070 auto in = r.out.next - dist;
1071 auto n = clamp(len, r.out.avail());
1072 len -= n;
1073 while(n--)
1074 *r.out.next++ = *in++;
1075 }
1076 }
1077 else if((op & 64) == 0)
1078 {
1079
1080 cp = &distcode_[cp->val + (bi_.peek_fast() & ((1U << op) - 1))];
1081 goto dodist;
1082 }
1083 else
1084 {
1085 BOOST_BEAST_ASSIGN_EC(ec, error::invalid_distance_code);
1086 mode_ = BAD;
1087 break;
1088 }
1089 }
1090 else if((op & 64) == 0)
1091 {
1092
1093 cp = &lencode_[cp->val + (bi_.peek_fast() & ((1U << op) - 1))];
1094 goto dolen;
1095 }
1096 else if(op & 32)
1097 {
1098
1099 mode_ = TYPE;
1100 break;
1101 }
1102 else
1103 {
1104 BOOST_BEAST_ASSIGN_EC(ec, error::invalid_literal_length);
1105 mode_ = BAD;
1106 break;
1107 }
1108 }
1109 while(r.in.next < last && r.out.next < end);
1110
1111
1112 bi_.rewind(r.in.next);
1113 }
1114
1115 }
1116 }
1117 }
1118 }
1119
1120 #endif