1// Copyright 2017 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "core/fxcodec/jbig2/JBig2_BitStream.h" 6 7#include <memory> 8#include <utility> 9 10#include "core/fpdfapi/parser/cpdf_stream_acc.h" 11#include "testing/gtest/include/gtest/gtest.h" 12#include "third_party/base/ptr_util.h" 13 14TEST(JBig2_BitStream, ReadNBits) { 15 std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); 16 data.get()[0] = 0xb1; // 10110001 17 18 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); 19 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 20 acc->LoadAllDataFiltered(); 21 22 CJBig2_BitStream stream(acc); 23 24 uint32_t val1; 25 EXPECT_EQ(0, stream.readNBits(1, &val1)); 26 EXPECT_EQ(1U, val1); 27 28 int32_t val2; 29 EXPECT_EQ(0, stream.readNBits(1, &val2)); 30 EXPECT_EQ(0, val2); 31 32 EXPECT_EQ(0, stream.readNBits(2, &val2)); 33 EXPECT_EQ(3, val2); 34 35 EXPECT_EQ(0, stream.readNBits(4, &val2)); 36 EXPECT_EQ(1, val2); 37} 38 39TEST(JBig2_BitStream, ReadNBitsLargerThenData) { 40 std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); 41 data.get()[0] = 0xb1; 42 43 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); 44 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 45 acc->LoadAllDataFiltered(); 46 47 CJBig2_BitStream stream(acc); 48 49 uint32_t val1; 50 EXPECT_EQ(0, stream.readNBits(10, &val1)); 51 EXPECT_EQ(0xb1U, val1); 52} 53 54TEST(JBig2_BitStream, ReadNBitsNullStream) { 55 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(nullptr, 0, nullptr); 56 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 57 acc->LoadAllDataFiltered(); 58 59 CJBig2_BitStream stream(acc); 60 61 uint32_t val1; 62 EXPECT_EQ(-1, stream.readNBits(1, &val1)); 63 64 int32_t val2; 65 EXPECT_EQ(-1, stream.readNBits(2, &val2)); 66} 67 68TEST(JBig2_BitStream, ReadNBitsEmptyStream) { 69 std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); 70 71 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 0, nullptr); 72 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 73 acc->LoadAllDataFiltered(); 74 75 CJBig2_BitStream stream(acc); 76 77 uint32_t val1; 78 EXPECT_EQ(-1, stream.readNBits(1, &val1)); 79 80 int32_t val2; 81 EXPECT_EQ(-1, stream.readNBits(2, &val2)); 82} 83 84TEST(JBig2_BitStream, ReadNBitsOutOfBounds) { 85 std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 1)); 86 data.get()[0] = 0xb1; // 10110001 87 88 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 1, nullptr); 89 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 90 acc->LoadAllDataFiltered(); 91 92 CJBig2_BitStream stream(acc); 93 94 uint32_t val1; 95 EXPECT_EQ(0, stream.readNBits(8, &val1)); 96 97 int32_t val2; 98 EXPECT_EQ(-1, stream.readNBits(2, &val2)); 99} 100 101TEST(JBig2_BitStream, ReadNBitsWhereNIs36) { 102 std::unique_ptr<uint8_t, FxFreeDeleter> data(FX_Alloc(uint8_t, 5)); 103 data.get()[0] = 0xb0; 104 data.get()[1] = 0x01; 105 data.get()[2] = 0x00; 106 data.get()[3] = 0x00; 107 data.get()[4] = 0x40; 108 109 auto in_stream = pdfium::MakeUnique<CPDF_Stream>(std::move(data), 5, nullptr); 110 auto acc = pdfium::MakeRetain<CPDF_StreamAcc>(in_stream.get()); 111 acc->LoadAllDataFiltered(); 112 113 CJBig2_BitStream stream(acc); 114 115 // This will shift off the top two bits and they end up lost. 116 uint32_t val1; 117 EXPECT_EQ(0, stream.readNBits(34, &val1)); 118 EXPECT_EQ(0xc0040001U, val1); 119} 120