@@ -1248,6 +1248,55 @@ TEST(ZlibTest, InflateCopySIGILLReproduction) {
12481248 }
12491249}
12501250
1251+ TEST (ZlibTest, InflateChunkRefillDistanceBitBudget) {
1252+ // Tests the edge case where one fast-loop iteration uses 10 + 10 + 15 + 5 +
1253+ // 15 = 55 of the 56 bits a refill. There should be sufficient bits for the
1254+ // next iteration.
1255+ static const uint8_t kCompressed [] = {
1256+ 0xcd , 0xef , 0x01 , 0x82 , 0x24 , 0x49 , 0x92 , 0x24 , 0x49 , 0x22 , 0xb1 , 0xa8 ,
1257+ 0x79 , 0xf5 , 0xec , 0x2f , 0x33 , 0xf3 , 0x17 , 0xf7 , 0x7a , 0xf8 , 0xc6 , 0x1d ,
1258+ 0x20 , 0xb1 , 0xa8 , 0x79 , 0x64 , 0xf5 , 0xec , 0xfd , 0xf3 , 0xef , 0xff , 0x1f ,
1259+ 0xfc , 0xff , 0xfe , 0xfd , 0xe7 , 0xdf , 0xff , 0x3f , 0xf8 , 0xff , 0xfd , 0xfb ,
1260+ 0xcf , 0xbf , 0xff , 0x7f , 0xf0 , 0xff , 0xfb , 0x17 };
1261+ std::vector<uint8_t > output (402 + 512 );
1262+ z_stream stream = {};
1263+ stream.next_in = const_cast <uint8_t *>(kCompressed );
1264+ stream.avail_in = sizeof (kCompressed );
1265+ stream.next_out = output.data ();
1266+ stream.avail_out = output.size ();
1267+
1268+ ASSERT_EQ (Z_OK , inflateInit2 (&stream, -MAX_WBITS ));
1269+ EXPECT_EQ (Z_STREAM_END , inflate (&stream, Z_FINISH ));
1270+ EXPECT_EQ (402u , stream.total_out );
1271+ EXPECT_EQ (Z_OK , inflateEnd (&stream));
1272+ EXPECT_EQ (' b' , output[133 ]); // Decodes as 'a' if the refill is not reached.
1273+ }
1274+
1275+ TEST (ZlibTest, InflateChunkRefillLiteralBitBudget) {
1276+ // Test an edge case where an iteration ends at a literal. and returns to the
1277+ // top of the inflate loop.
1278+ static const uint8_t kCompressed [] = {
1279+ 0x05 , 0xe0 , 0x81 , 0x81 , 0x04 , 0x49 , 0x92 , 0x24 , 0x49 , 0xb2 , 0xa8 , 0x79 ,
1280+ 0x64 , 0xcf , 0x1e , 0x96 , 0x55 , 0x05 , 0xc5 , 0x3f , 0xf4 , 0x44 , 0xff , 0xfe ,
1281+ 0xf7 , 0xcf , 0x3f , 0xff , 0xbf , 0x7f , 0xff , 0xfb , 0xe7 , 0x9f , 0xff , 0xdf ,
1282+ 0xbf , 0xff , 0xfd , 0xf3 , 0xcf , 0xff , 0xef , 0xdf , 0xff , 0xfe , 0xf9 , 0xe7 ,
1283+ 0xff , 0xf7 , 0xef , 0x7f , 0xff , 0xfc , 0xf3 , 0xff , 0xfb , 0xf7 , 0xbf , 0x7f ,
1284+ 0xfe , 0xf9 , 0xff , 0x01 };
1285+ std::vector<uint8_t > output (30 + 512 );
1286+ z_stream stream = {};
1287+ stream.next_in = const_cast <uint8_t *>(kCompressed );
1288+ stream.avail_in = sizeof (kCompressed );
1289+ stream.next_out = output.data ();
1290+ stream.avail_out = output.size ();
1291+
1292+ ASSERT_EQ (Z_OK , inflateInit2 (&stream, -MAX_WBITS ));
1293+ EXPECT_EQ (Z_STREAM_END , inflate (&stream, Z_FINISH ));
1294+ EXPECT_EQ (30u , stream.total_out );
1295+ EXPECT_EQ (Z_OK , inflateEnd (&stream));
1296+ // Decodes as 'a' if the accumulator runs short before the next lookup.
1297+ EXPECT_EQ (' b' , output[5 ]);
1298+ }
1299+
12511300// TODO(gustavoa): make these tests run standalone.
12521301#ifndef CMAKE_STANDALONE_UNITTESTS
12531302
@@ -1513,3 +1562,4 @@ TEST(ZlibTest, Compare256ReachesMaxMatch) {
15131562}
15141563
15151564#endif
1565+
0 commit comments