1 // Copyright 2016 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 <stdint.h>
6 
7 #include <limits>
8 #include <memory>
9 
10 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
11 #include "core/fxcodec/basic/basicmodule.h"
12 #include "core/fxcrt/fx_memory_wrappers.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
TEST(fxcodec,RLETestBadInputs)15 TEST(fxcodec, RLETestBadInputs) {
16   const uint8_t src_buf[] = {1};
17   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
18   uint32_t dest_size = 0;
19 
20   // Error codes, not segvs, should callers pass us a nullptr pointer.
21   EXPECT_FALSE(BasicModule::RunLengthEncode(src_buf, &dest_buf, nullptr));
22   EXPECT_FALSE(BasicModule::RunLengthEncode(src_buf, nullptr, &dest_size));
23   EXPECT_FALSE(BasicModule::RunLengthEncode({}, &dest_buf, &dest_size));
24 }
25 
26 // Check length 1 input works. Check terminating character is applied.
TEST(fxcodec,RLETestShortInput)27 TEST(fxcodec, RLETestShortInput) {
28   const uint8_t src_buf[] = {1};
29   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
30   uint32_t dest_size = 0;
31 
32   EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf, &dest_buf, &dest_size));
33   ASSERT_EQ(3u, dest_size);
34   auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
35   EXPECT_EQ(0, dest_buf_span[0]);
36   EXPECT_EQ(1, dest_buf_span[1]);
37   EXPECT_EQ(128, dest_buf_span[2]);
38 }
39 
40 // Check a few basic cases (2 matching runs in a row, matching run followed
41 // by a non-matching run, and non-matching run followed by a matching run).
TEST(fxcodec,RLETestNormalInputs)42 TEST(fxcodec, RLETestNormalInputs) {
43   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
44   uint32_t dest_size = 0;
45   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
46   uint32_t decoded_size = 0;
47 
48   {
49     // Case 1: Match, match
50     const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
51     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
52     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
53     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
54     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
55     for (uint32_t i = 0; i < decoded_size; i++)
56       EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
57   }
58 
59   {
60     // Case 2: Match, non-match
61     const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
62     dest_buf.reset();
63     dest_size = 0;
64     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
65     decoded_buf.reset();
66     decoded_size = 0;
67     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
68     ASSERT_EQ(sizeof(src_buf_2), decoded_size);
69     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
70     for (uint32_t i = 0; i < decoded_size; i++)
71       EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
72   }
73 
74   {
75     // Case 3: Non-match, match
76     const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
77     dest_buf.reset();
78     dest_size = 0;
79     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
80     decoded_buf.reset();
81     decoded_size = 0;
82     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
83     ASSERT_EQ(sizeof(src_buf_3), decoded_size);
84     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
85     for (uint32_t i = 0; i < decoded_size; i++)
86       EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
87   }
88 }
89 
90 // Check that runs longer than 128 are broken up properly, both matched and
91 // non-matched.
TEST(fxcodec,RLETestFullLengthInputs)92 TEST(fxcodec, RLETestFullLengthInputs) {
93   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
94   uint32_t dest_size = 0;
95   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
96   uint32_t decoded_size = 0;
97 
98   {
99     // Case 1: Match, match
100     const uint8_t src_buf_1[260] = {1};
101     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
102     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
103     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
104     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
105     for (uint32_t i = 0; i < decoded_size; i++)
106       EXPECT_EQ(src_buf_1[i], decoded_buf_span[i]) << " at " << i;
107   }
108 
109   {
110     // Case 2: Match, non-match
111     uint8_t src_buf_2[260] = {2};
112     for (uint16_t i = 128; i < 260; i++)
113       src_buf_2[i] = static_cast<uint8_t>(i - 125);
114     dest_buf.reset();
115     dest_size = 0;
116     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
117     decoded_buf.reset();
118     decoded_size = 0;
119     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
120     ASSERT_EQ(sizeof(src_buf_2), decoded_size);
121     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
122     for (uint32_t i = 0; i < decoded_size; i++)
123       EXPECT_EQ(src_buf_2[i], decoded_buf_span[i]) << " at " << i;
124   }
125 
126   {
127     // Case 3: Non-match, match
128     uint8_t src_buf_3[260] = {3};
129     for (uint8_t i = 0; i < 128; i++)
130       src_buf_3[i] = i;
131     dest_buf.reset();
132     dest_size = 0;
133     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
134     decoded_buf.reset();
135     decoded_size = 0;
136     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
137     ASSERT_EQ(sizeof(src_buf_3), decoded_size);
138     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
139     for (uint32_t i = 0; i < decoded_size; i++)
140       EXPECT_EQ(src_buf_3[i], decoded_buf_span[i]) << " at " << i;
141   }
142 
143   {
144     // Case 4: Non-match, non-match
145     uint8_t src_buf_4[260];
146     for (uint16_t i = 0; i < 260; i++)
147       src_buf_4[i] = static_cast<uint8_t>(i);
148     dest_buf.reset();
149     dest_size = 0;
150     EXPECT_TRUE(BasicModule::RunLengthEncode(src_buf_4, &dest_buf, &dest_size));
151     decoded_buf.reset();
152     decoded_size = 0;
153     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
154     ASSERT_EQ(sizeof(src_buf_4), decoded_size);
155     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
156     for (uint32_t i = 0; i < decoded_size; i++)
157       EXPECT_EQ(src_buf_4[i], decoded_buf_span[i]) << " at " << i;
158   }
159 }
160