Fix encode zero bits on word boundary bug
authorAndrey Tuganov <andreyt@google.com>
Mon, 28 Aug 2017 17:18:45 +0000 (13:18 -0400)
committerAndrey Tuganov <andreyt@google.com>
Mon, 28 Aug 2017 17:36:39 +0000 (13:36 -0400)
Bit stream writer was manifesting incorrect behaviour when the following
two conditions were met:
- writer was on 64-bit word boundary
- WriteBits was invoked with num_bits=0 (can happen when a Huffman codec has only one
value)

The bug was causing very rare sporadic corruption which was detected by
tests after a random experimental change in MARK-V model.

source/util/bit_stream.cpp
test/bit_stream.cpp

index bfd6af0..56f3700 100644 (file)
@@ -300,6 +300,8 @@ void BitWriterWord64::WriteBits(uint64_t bits, size_t num_bits) {
   assert(is_little_endian && "Big-endian architecture support not implemented");
   if (!is_little_endian) return;
 
+  if (num_bits == 0) return;
+
   bits = GetLowerBits(bits, num_bits);
 
   EmitSequence(bits, num_bits);
index 3fcdc14..dfc6d18 100644 (file)
@@ -565,6 +565,25 @@ TEST(BitWriterWord64, WriteBits) {
   EXPECT_EQ(PadToWord<64>("110011100111001"), writer.GetStreamPadded64());
 }
 
+TEST(BitWriterWord64, WriteZeroBits) {
+  BitWriterWord64 writer;
+  writer.WriteBits(0, 0);
+  writer.WriteBits(1, 0);
+  EXPECT_EQ(0u, writer.GetNumBits());
+  writer.WriteBits(1, 1);
+  writer.WriteBits(0, 0);
+  EXPECT_EQ(PadToWord<64>("1"), writer.GetStreamPadded64());
+  writer.WriteBits(0, 63);
+  EXPECT_EQ(64u, writer.GetNumBits());
+  writer.WriteBits(0, 0);
+  writer.WriteBits(7, 3);
+  writer.WriteBits(0, 0);
+  EXPECT_EQ(PadToWord<64>(
+          "1"
+          "000000000000000000000000000000000000000000000000000000000000000"
+          "111"), writer.GetStreamPadded64());
+}
+
 TEST(BitWriterWord64, ComparisonTestWriteLotsOfBits) {
   BitWriterStringStream writer1;
   BitWriterWord64 writer2(16384);