• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
10 #include "core/fxcodec/codec/ccodec_basicmodule.h"
11 #include "core/fxcodec/fx_codec.h"
12 #include "testing/fx_string_testhelpers.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   uint8_t* dest_buf = nullptr;
18   uint32_t src_size = 4;
19   uint32_t dest_size = 0;
20 
21   CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
22   EXPECT_TRUE(pEncoders);
23 
24   // Error codes, not segvs, should callers pass us a nullptr pointer.
25   EXPECT_FALSE(
26       pEncoders->RunLengthEncode(src_buf, src_size, &dest_buf, nullptr));
27   EXPECT_FALSE(
28       pEncoders->RunLengthEncode(src_buf, src_size, nullptr, &dest_size));
29   EXPECT_FALSE(pEncoders->RunLengthEncode(src_buf, 0, &dest_buf, &dest_size));
30   EXPECT_FALSE(
31       pEncoders->RunLengthEncode(nullptr, src_size, &dest_buf, &dest_size));
32 }
33 
34 // Check length 1 input works. Check terminating character is applied.
TEST(fxcodec,RLETestShortInput)35 TEST(fxcodec, RLETestShortInput) {
36   const uint8_t src_buf[] = {1};
37   uint8_t* dest_buf = nullptr;
38   uint32_t src_size = 1;
39   uint32_t dest_size = 0;
40 
41   CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
42   EXPECT_TRUE(pEncoders);
43 
44   EXPECT_TRUE(
45       pEncoders->RunLengthEncode(src_buf, src_size, &dest_buf, &dest_size));
46   ASSERT_EQ(3u, dest_size);
47   EXPECT_EQ(0, dest_buf[0]);
48   EXPECT_EQ(1, dest_buf[1]);
49   EXPECT_EQ(128, dest_buf[2]);
50 
51   FX_Free(dest_buf);
52 }
53 
54 // Check a few basic cases (2 matching runs in a row, matching run followed
55 // by a non-matching run, and non-matching run followed by a matching run).
TEST(fxcodec,RLETestNormalInputs)56 TEST(fxcodec, RLETestNormalInputs) {
57   // Match, match
58   const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
59 
60   // Match, non-match
61   const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
62 
63   // Non-match, match
64   const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
65 
66   uint32_t src_size = 10;
67   uint32_t dest_size = 0;
68   uint8_t* dest_buf = nullptr;
69 
70   CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
71   EXPECT_TRUE(pEncoders);
72 
73   // Case 1:
74   EXPECT_TRUE(
75       pEncoders->RunLengthEncode(src_buf_1, src_size, &dest_buf, &dest_size));
76   uint8_t* decoded_buf = nullptr;
77   uint32_t decoded_size = 0;
78   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
79   ASSERT_EQ(src_size, decoded_size);
80   for (uint32_t i = 0; i < src_size; i++)
81     EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i;
82   FX_Free(dest_buf);
83   FX_Free(decoded_buf);
84 
85   // Case 2:
86   dest_buf = nullptr;
87   dest_size = 0;
88   EXPECT_TRUE(
89       pEncoders->RunLengthEncode(src_buf_2, src_size, &dest_buf, &dest_size));
90   decoded_buf = nullptr;
91   decoded_size = 0;
92   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
93   ASSERT_EQ(src_size, decoded_size);
94   for (uint32_t i = 0; i < src_size; i++)
95     EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i;
96   FX_Free(dest_buf);
97   FX_Free(decoded_buf);
98 
99   // Case 3:
100   dest_buf = nullptr;
101   dest_size = 0;
102   EXPECT_TRUE(
103       pEncoders->RunLengthEncode(src_buf_3, src_size, &dest_buf, &dest_size));
104   decoded_buf = nullptr;
105   decoded_size = 0;
106   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
107   ASSERT_EQ(src_size, decoded_size);
108   for (uint32_t i = 0; i < src_size; i++)
109     EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i;
110   FX_Free(dest_buf);
111   FX_Free(decoded_buf);
112 }
113 
114 // Check that runs longer than 128 are broken up properly, both matched and
115 // non-matched.
TEST(fxcodec,RLETestFullLengthInputs)116 TEST(fxcodec, RLETestFullLengthInputs) {
117   // Match, match
118   const uint8_t src_buf_1[260] = {1};
119 
120   // Match, non-match
121   uint8_t src_buf_2[260] = {2};
122   for (uint16_t i = 128; i < 260; i++)
123     src_buf_2[i] = (uint8_t)(i - 125);
124 
125   // Non-match, match
126   uint8_t src_buf_3[260] = {3};
127   for (uint8_t i = 0; i < 128; i++)
128     src_buf_3[i] = i;
129 
130   // Non-match, non-match
131   uint8_t src_buf_4[260];
132   for (uint16_t i = 0; i < 260; i++)
133     src_buf_4[i] = (uint8_t)(i);
134 
135   uint32_t src_size = 260;
136   uint32_t dest_size = 0;
137   uint8_t* dest_buf = nullptr;
138 
139   CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
140   EXPECT_TRUE(pEncoders);
141 
142   // Case 1:
143   EXPECT_TRUE(
144       pEncoders->RunLengthEncode(src_buf_1, src_size, &dest_buf, &dest_size));
145   uint8_t* decoded_buf = nullptr;
146   uint32_t decoded_size = 0;
147   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
148   ASSERT_EQ(src_size, decoded_size);
149   for (uint32_t i = 0; i < src_size; i++)
150     EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i;
151   FX_Free(dest_buf);
152   FX_Free(decoded_buf);
153 
154   // Case 2:
155   dest_buf = nullptr;
156   dest_size = 0;
157   EXPECT_TRUE(
158       pEncoders->RunLengthEncode(src_buf_2, src_size, &dest_buf, &dest_size));
159   decoded_buf = nullptr;
160   decoded_size = 0;
161   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
162   ASSERT_EQ(src_size, decoded_size);
163   for (uint32_t i = 0; i < src_size; i++)
164     EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i;
165   FX_Free(dest_buf);
166   FX_Free(decoded_buf);
167 
168   // Case 3:
169   dest_buf = nullptr;
170   dest_size = 0;
171   EXPECT_TRUE(
172       pEncoders->RunLengthEncode(src_buf_3, src_size, &dest_buf, &dest_size));
173   decoded_buf = nullptr;
174   decoded_size = 0;
175   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
176   ASSERT_EQ(src_size, decoded_size);
177   for (uint32_t i = 0; i < src_size; i++)
178     EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i;
179   FX_Free(dest_buf);
180   FX_Free(decoded_buf);
181 
182   // Case 4:
183   dest_buf = nullptr;
184   dest_size = 0;
185   EXPECT_TRUE(
186       pEncoders->RunLengthEncode(src_buf_4, src_size, &dest_buf, &dest_size));
187   decoded_buf = nullptr;
188   decoded_size = 0;
189   RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size);
190   ASSERT_EQ(src_size, decoded_size);
191   for (uint32_t i = 0; i < src_size; i++)
192     EXPECT_EQ(src_buf_4[i], decoded_buf[i]) << " at " << i;
193   FX_Free(dest_buf);
194   FX_Free(decoded_buf);
195 }
196