| // Copyright 2017 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "core/fxcodec/jbig2/JBig2_BitStream.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "core/fpdfapi/parser/cpdf_stream_acc.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/base/ptr_util.h" |
| |
| TEST(JBig2_BitStream, ReadNBits) { |
| std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); |
| data.get()[0] = 0xb1; // 10110001 |
| |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| uint32_t val1; |
| EXPECT_EQ(0, stream.readNBits(1, &val1)); |
| EXPECT_EQ(1U, val1); |
| |
| int32_t val2; |
| EXPECT_EQ(0, stream.readNBits(1, &val2)); |
| EXPECT_EQ(0, val2); |
| |
| EXPECT_EQ(0, stream.readNBits(2, &val2)); |
| EXPECT_EQ(3, val2); |
| |
| EXPECT_EQ(0, stream.readNBits(4, &val2)); |
| EXPECT_EQ(1, val2); |
| } |
| |
| TEST(JBig2_BitStream, ReadNBitsLargerThenData) { |
| std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); |
| data.get()[0] = 0xb1; |
| |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| uint32_t val1; |
| EXPECT_EQ(0, stream.readNBits(10, &val1)); |
| EXPECT_EQ(0xb1U, val1); |
| } |
| |
| TEST(JBig2_BitStream, ReadNBitsNullStream) { |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(nullptr, 0, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| uint32_t val1; |
| EXPECT_EQ(-1, stream.readNBits(1, &val1)); |
| |
| int32_t val2; |
| EXPECT_EQ(-1, stream.readNBits(2, &val2)); |
| } |
| |
| TEST(JBig2_BitStream, ReadNBitsEmptyStream) { |
| std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); |
| |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 0, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| uint32_t val1; |
| EXPECT_EQ(-1, stream.readNBits(1, &val1)); |
| |
| int32_t val2; |
| EXPECT_EQ(-1, stream.readNBits(2, &val2)); |
| } |
| |
| TEST(JBig2_BitStream, ReadNBitsOutOfBounds) { |
| std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); |
| data.get()[0] = 0xb1; // 10110001 |
| |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| uint32_t val1; |
| EXPECT_EQ(0, stream.readNBits(8, &val1)); |
| |
| int32_t val2; |
| EXPECT_EQ(-1, stream.readNBits(2, &val2)); |
| } |
| |
| TEST(JBig2_BitStream, ReadNBitsWhereNIs36) { |
| std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 5)); |
| data.get()[0] = 0xb0; |
| data.get()[1] = 0x01; |
| data.get()[2] = 0x00; |
| data.get()[3] = 0x00; |
| data.get()[4] = 0x40; |
| |
| auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 5, nullptr); |
| auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); |
| acc->LoadAllDataFiltered(); |
| |
| CJBig2_BitStream stream(acc); |
| |
| // This will shift off the top two bits and they end up lost. |
| uint32_t val1; |
| EXPECT_EQ(0, stream.readNBits(34, &val1)); |
| EXPECT_EQ(0xc0040001U, val1); |
| } |