Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfx_gifcontext_unittest.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
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/gif/cfx_gifcontext.h"
6
7#include <stdint.h>
8
9#include <array>
10#include <utility>
11
12#include "core/fxcodec/cfx_codec_memory.h"
13#include "core/fxcrt/data_vector.h"
14#include "core/fxcrt/stl_util.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace fxcodec {
18
19class CFX_GifContextForTest final : public CFX_GifContext {
20 public:
22 ~CFX_GifContextForTest() override = default;
23
24 using CFX_GifContext::ReadAllOrNone;
25 using CFX_GifContext::ReadGifSignature;
26 using CFX_GifContext::ReadLogicalScreenDescriptor;
27
28 CFX_CodecMemory* InputBuffer() const { return input_buffer_.Get(); }
29 void SetTestInputBuffer(pdfium::span<const uint8_t> input) {
30 auto pMemory = pdfium::MakeRetain<CFX_CodecMemory>(input.size());
31 fxcrt::Copy(input, pMemory->GetBufferSpan());
32 SetInputBuffer(std::move(pMemory));
33 }
34};
35
37 uint8_t buffer[] = {0x00, 0x01, 0x02};
38 CFX_GifContextForTest context;
39
40 context.SetTestInputBuffer({});
41 EXPECT_EQ(0u, context.InputBuffer()->GetSize());
42 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
43
44 context.SetTestInputBuffer(pdfium::make_span(buffer).first(0u));
45 EXPECT_EQ(0u, context.InputBuffer()->GetSize());
46 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
47
48 context.SetTestInputBuffer(buffer);
49 EXPECT_EQ(3u, context.InputBuffer()->GetSize());
50 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
51}
52
54 CFX_GifContextForTest context;
55 context.SetTestInputBuffer({});
56 EXPECT_FALSE(context.ReadAllOrNone(pdfium::span<uint8_t>()));
57
58 auto src_buffer = fxcrt::ToArray<const uint8_t>(
59 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09});
60
61 DataVector<uint8_t> dest_buffer(src_buffer.size());
62 auto dest_span = pdfium::make_span(dest_buffer);
63
64 context.SetTestInputBuffer(pdfium::make_span(src_buffer).first(1u));
65 EXPECT_FALSE(context.ReadAllOrNone(dest_buffer));
66 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
67 EXPECT_TRUE(context.ReadAllOrNone(dest_span.first(1u)));
68 EXPECT_EQ(src_buffer[0], dest_buffer[0]);
69
70 context.SetTestInputBuffer(src_buffer);
71 EXPECT_TRUE(context.ReadAllOrNone(dest_span.first(src_buffer.size())));
72 for (size_t i = 0; i < src_buffer.size(); i++) {
73 EXPECT_EQ(src_buffer[i], dest_buffer[i]);
74 }
75 context.SetTestInputBuffer(src_buffer);
76 for (size_t i = 0; i < src_buffer.size(); i++) {
77 EXPECT_TRUE(context.ReadAllOrNone(dest_span.first(1u)));
78 EXPECT_EQ(src_buffer[i], dest_buffer[0]);
79 }
80}
81
83 CFX_GifContextForTest context;
84 {
85 uint8_t data[1];
86 context.SetTestInputBuffer(pdfium::make_span(data).first(0u));
88 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
89 context.SetTestInputBuffer({});
90 }
91 // Make sure testing the entire signature
92 {
93 uint8_t data[] = {'G', 'I', 'F'};
94 context.SetTestInputBuffer(data);
96 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
97 context.SetTestInputBuffer({});
98 }
99 {
100 uint8_t data[] = {'N', 'O', 'T', 'G', 'I', 'F'};
101 context.SetTestInputBuffer(data);
103 EXPECT_EQ(6u, context.InputBuffer()->GetPosition());
104 context.SetTestInputBuffer({});
105 }
106 // Make sure not matching GIF8*a
107 {
108 uint8_t data[] = {'G', 'I', 'F', '8', '0', 'a'};
109 context.SetTestInputBuffer(data);
111 EXPECT_EQ(6u, context.InputBuffer()->GetPosition());
112 context.SetTestInputBuffer({});
113 }
114 // Make sure not matching GIF**a
115 {
116 uint8_t data[] = {'G', 'I', 'F', '9', '2', 'a'};
117 context.SetTestInputBuffer(data);
119 EXPECT_EQ(6u, context.InputBuffer()->GetPosition());
120 context.SetTestInputBuffer({});
121 }
122 // One valid signature
123 {
124 uint8_t data[] = {'G', 'I', 'F', '8', '7', 'a'};
125 context.SetTestInputBuffer(data);
127 EXPECT_EQ(6u, context.InputBuffer()->GetPosition());
128 context.SetTestInputBuffer({});
129 }
130 // The other valid signature
131 {
132 uint8_t data[] = {'G', 'I', 'F', '8', '9', 'a'};
133 context.SetTestInputBuffer(data);
135 EXPECT_EQ(6u, context.InputBuffer()->GetPosition());
136 context.SetTestInputBuffer({});
137 }
138}
139
141 CFX_GifContextForTest context;
142 {
143 uint8_t data[1];
144 context.SetTestInputBuffer(pdfium::make_span(data).first(0u));
147 context.SetTestInputBuffer({});
148 }
149 // LSD with all the values zero'd
150 {
151 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)] = {};
152 context.SetTestInputBuffer(lsd);
153
156
157 EXPECT_EQ(sizeof(CFX_GifLocalScreenDescriptor),
158 static_cast<size_t>(context.InputBuffer()->GetPosition()));
159 EXPECT_EQ(0, context.width_);
160 EXPECT_EQ(0, context.height_);
161 EXPECT_EQ(0u, context.bc_index_);
162 context.SetTestInputBuffer({});
163 }
164 // LSD with no global palette
165 {
166 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)] = {0x0A, 0x00, 0x00, 0x0F,
167 0x00, 0x01, 0x02};
168 context.SetTestInputBuffer(lsd);
169
172
173 EXPECT_EQ(sizeof(CFX_GifLocalScreenDescriptor),
174 static_cast<size_t>(context.InputBuffer()->GetPosition()));
175 EXPECT_EQ(0x000A, context.width_);
176 EXPECT_EQ(0x0F00, context.height_);
177 EXPECT_EQ(0u, context.bc_index_); // bc_index_ is 0 if no global palette
178 context.SetTestInputBuffer({});
179 }
180 // LSD with global palette bit set, but no global palette
181 {
182 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)] = {0x0A, 0x00, 0x00, 0x0F,
183 0x80, 0x01, 0x02};
184 context.SetTestInputBuffer(lsd);
185
188
189 EXPECT_EQ(0u, context.InputBuffer()->GetPosition());
190 context.SetTestInputBuffer({});
191 }
192 // LSD with global palette
193 {
194 struct {
195 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
196 uint8_t palette[4 * sizeof(CFX_GifPalette)];
197 } data = {{0x0A, 0x00, 0x00, 0x0F, 0xA9, 0x01, 0x02},
198 {0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1}};
199 context.SetTestInputBuffer(pdfium::as_bytes(pdfium::span_from_ref(data)));
202
203 EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition());
204 EXPECT_EQ(0x000A, context.width_);
205 EXPECT_EQ(0x0F00, context.height_);
206 EXPECT_EQ(1u, context.bc_index_);
207 EXPECT_EQ(1u, context.global_palette_exp_);
208 EXPECT_EQ(1, context.global_sort_flag_);
209 EXPECT_EQ(2, context.global_color_resolution_);
210 EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(),
211 sizeof(data.palette)));
212 context.SetTestInputBuffer({});
213 }
214}
215
217 CFX_GifContextForTest context;
218 // Bad signature
219 {
220 struct {
221 uint8_t signature[6];
222 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
223 } data = {{'N', 'O', 'T', 'G', 'I', 'F'},
224 {0x0A, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x02}};
225 context.SetTestInputBuffer(pdfium::as_bytes(pdfium::span_from_ref(data)));
226 EXPECT_EQ(GifDecoder::Status::kError, context.ReadHeader());
227 EXPECT_EQ(sizeof(data.signature), context.InputBuffer()->GetPosition());
228 context.SetTestInputBuffer({});
229 }
230 // Short after signature
231 {
232 uint8_t signature[] = {'G', 'I', 'F', '8', '7', 'a'};
233 context.SetTestInputBuffer(signature);
234 EXPECT_EQ(GifDecoder::Status::kUnfinished, context.ReadHeader());
235 EXPECT_EQ(sizeof(signature), context.InputBuffer()->GetPosition());
236 context.SetTestInputBuffer({});
237 }
238 // Success without global palette
239 {
240 struct {
241 uint8_t signature[6];
242 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
243 } data = {{'G', 'I', 'F', '8', '7', 'a'},
244 {0x0A, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x02}};
245 context.SetTestInputBuffer(pdfium::as_bytes(pdfium::span_from_ref(data)));
246 EXPECT_EQ(GifDecoder::Status::kSuccess, context.ReadHeader());
247 EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition());
248 EXPECT_EQ(0x000A, context.width_);
249 EXPECT_EQ(0x0F00, context.height_);
250 EXPECT_EQ(0u, context.bc_index_); // bc_index_ is 0 if no global palette
251 context.SetTestInputBuffer({});
252 }
253 // Missing Global Palette
254 {
255 struct {
256 uint8_t signature[6];
257 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
258 } data = {{'G', 'I', 'F', '8', '7', 'a'},
259 {0x0A, 0x00, 0x00, 0x0F, 0x80, 0x01, 0x02}};
260 context.SetTestInputBuffer(pdfium::as_bytes(pdfium::span_from_ref(data)));
261 EXPECT_EQ(GifDecoder::Status::kUnfinished, context.ReadHeader());
262 EXPECT_EQ(sizeof(data.signature), context.InputBuffer()->GetPosition());
263 context.SetTestInputBuffer({});
264 }
265 // Success with global palette
266 {
267 struct {
268 uint8_t signature[6];
269 uint8_t lsd[sizeof(CFX_GifLocalScreenDescriptor)];
270 uint8_t palette[4 * sizeof(CFX_GifPalette)];
271 } data = {{'G', 'I', 'F', '8', '7', 'a'},
272 {0x0A, 0x00, 0x00, 0x0F, 0xA9, 0x01, 0x02},
273 {0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1}};
274 context.SetTestInputBuffer(pdfium::as_bytes(pdfium::span_from_ref(data)));
275 EXPECT_EQ(GifDecoder::Status::kSuccess, context.ReadHeader());
276 EXPECT_EQ(sizeof(data), context.InputBuffer()->GetPosition());
277 EXPECT_EQ(0x000A, context.width_);
278 EXPECT_EQ(0x0F00, context.height_);
279 EXPECT_EQ(1u, context.bc_index_);
280 EXPECT_EQ(1u, context.global_palette_exp_);
281 EXPECT_EQ(1, context.global_sort_flag_);
282 EXPECT_EQ(2, context.global_color_resolution_);
283 EXPECT_EQ(0, memcmp(data.palette, context.global_palette_.data(),
284 sizeof(data.palette)));
285 context.SetTestInputBuffer({});
286 }
287}
288
289} // namespace fxcodec
void SetTestInputBuffer(pdfium::span< const uint8_t > input)
~CFX_GifContextForTest() override=default
CFX_GifContext(GifDecoder::Delegate *delegate)
void SetInputBuffer(RetainPtr< CFX_CodecMemory > codec_memory)
GifDecoder::Status ReadHeader()
GifDecoder::Status ReadLogicalScreenDescriptor()
GifDecoder::Status ReadGifSignature()
TEST(CFX_GifContext, SetInputBuffer)