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 
TEST(JBig2_BitStream,ReadNBits)14 TEST(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 
TEST(JBig2_BitStream,ReadNBitsLargerThenData)39 TEST(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 
TEST(JBig2_BitStream,ReadNBitsNullStream)54 TEST(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 
TEST(JBig2_BitStream,ReadNBitsEmptyStream)68 TEST(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 
TEST(JBig2_BitStream,ReadNBitsOutOfBounds)84 TEST(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 
TEST(JBig2_BitStream,ReadNBitsWhereNIs36)101 TEST(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