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