xref: /aosp_15_r20/external/skia/tests/DescriptorTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2019 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkDescriptor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkScalerContext.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkWriteBuffer.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
18*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
19*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
20*c8dee2aaSAndroid Build Coastguard Worker #include <optional>
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker class SkDescriptorTestHelper {
23*c8dee2aaSAndroid Build Coastguard Worker public:
SetLength(SkDescriptor * desc,size_t length)24*c8dee2aaSAndroid Build Coastguard Worker     static void SetLength(SkDescriptor* desc, size_t length) { desc->fLength = length; }
SetCount(SkDescriptor * desc,uint32_t count)25*c8dee2aaSAndroid Build Coastguard Worker     static void SetCount(SkDescriptor* desc, uint32_t count) { desc->fCount = count; }
26*c8dee2aaSAndroid Build Coastguard Worker };
27*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_empty,r)28*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_empty, r) {
29*c8dee2aaSAndroid Build Coastguard Worker     const size_t size = sizeof(SkDescriptor);
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
32*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->isValid());
33*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->getLength() == size);
34*c8dee2aaSAndroid Build Coastguard Worker }
35*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_valid_simple,r)36*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_valid_simple, r) {
37*c8dee2aaSAndroid Build Coastguard Worker     const size_t size =
38*c8dee2aaSAndroid Build Coastguard Worker             sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
41*c8dee2aaSAndroid Build Coastguard Worker     SkScalerContextRec rec;
42*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
43*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->isValid());
44*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->getLength() == size);
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
47*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
48*c8dee2aaSAndroid Build Coastguard Worker }
49*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_valid_simple_extra_space,r)50*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_valid_simple_extra_space, r) {
51*c8dee2aaSAndroid Build Coastguard Worker     const size_t extra_space = 100;
52*c8dee2aaSAndroid Build Coastguard Worker     const size_t size =
53*c8dee2aaSAndroid Build Coastguard Worker             sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);
54*c8dee2aaSAndroid Build Coastguard Worker 
55*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size + extra_space);
56*c8dee2aaSAndroid Build Coastguard Worker     SkScalerContextRec rec;
57*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
58*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->isValid());
59*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->getLength() == size);
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
62*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
63*c8dee2aaSAndroid Build Coastguard Worker }
64*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_valid_more_tags,r)65*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_valid_more_tags, r) {
66*c8dee2aaSAndroid Build Coastguard Worker     const size_t effectSize = 16;
67*c8dee2aaSAndroid Build Coastguard Worker     const size_t testSize = 32;
68*c8dee2aaSAndroid Build Coastguard Worker     const size_t size = sizeof(SkDescriptor) + 3 * sizeof(SkDescriptor::Entry) +
69*c8dee2aaSAndroid Build Coastguard Worker                         sizeof(SkScalerContextRec) + effectSize + testSize;
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
72*c8dee2aaSAndroid Build Coastguard Worker     SkScalerContextRec rec;
73*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
74*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kEffects_SkDescriptorTag, effectSize, nullptr);
75*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(SkSetFourByteTag('t', 'e', 's', 't'), testSize, nullptr);
76*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->isValid());
77*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->getLength() == size);
78*c8dee2aaSAndroid Build Coastguard Worker 
79*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
80*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
81*c8dee2aaSAndroid Build Coastguard Worker }
82*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_invalid_rec_size,r)83*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_invalid_rec_size, r) {
84*c8dee2aaSAndroid Build Coastguard Worker     const size_t size =
85*c8dee2aaSAndroid Build Coastguard Worker             sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) - 4;
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
88*c8dee2aaSAndroid Build Coastguard Worker     SkScalerContextRec rec;
89*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec) - 4, &rec);
90*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->getLength() == size);
91*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
92*c8dee2aaSAndroid Build Coastguard Worker }
93*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_invalid_length,r)94*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_invalid_length, r) {
95*c8dee2aaSAndroid Build Coastguard Worker     const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);
96*c8dee2aaSAndroid Build Coastguard Worker     const size_t effect_size = 1000;
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
99*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size);
102*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size + effect_size);
105*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, desc->isValid());
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_entry_too_big,r)108*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_entry_too_big, r) {
109*c8dee2aaSAndroid Build Coastguard Worker     const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + 4;
110*c8dee2aaSAndroid Build Coastguard Worker     // Must be less than fLength, but big enough to be bigger then fLength when added.
111*c8dee2aaSAndroid Build Coastguard Worker     const size_t effect_size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(size);
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);
116*c8dee2aaSAndroid Build Coastguard Worker 
117*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size);
118*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetCount(desc.get(), 2);
119*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
120*c8dee2aaSAndroid Build Coastguard Worker 
121*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), size);
122*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetCount(desc.get(), 1);
123*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
124*c8dee2aaSAndroid Build Coastguard Worker }
125*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_entry_over_end,r)126*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_entry_over_end, r) {
127*c8dee2aaSAndroid Build Coastguard Worker     auto desc = SkDescriptor::Alloc(36);
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker     // Make the start of the Entry be in the SkDescriptor, but the second half falls out side the
130*c8dee2aaSAndroid Build Coastguard Worker     // SkDescriptor. So: 12 (for descriptor) + 8 (for entry) + 12 (for entry length) = 32. An
131*c8dee2aaSAndroid Build Coastguard Worker     // An Entry is 8 bytes, so 4 bytes are < 36 and 4 bytes > 36.
132*c8dee2aaSAndroid Build Coastguard Worker     desc->addEntry(kEffects_SkDescriptorTag, 12, nullptr);
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetLength(desc.get(), 36);
135*c8dee2aaSAndroid Build Coastguard Worker     SkDescriptorTestHelper::SetCount(desc.get(), 2);
136*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(r, !desc->isValid());
137*c8dee2aaSAndroid Build Coastguard Worker }
138*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Descriptor_flatten_unflatten,r)139*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Descriptor_flatten_unflatten, r) {
140*c8dee2aaSAndroid Build Coastguard Worker     {
141*c8dee2aaSAndroid Build Coastguard Worker         SkBinaryWriteBuffer writer({});
142*c8dee2aaSAndroid Build Coastguard Worker         auto desc = SkDescriptor::Alloc(sizeof(SkDescriptor));
143*c8dee2aaSAndroid Build Coastguard Worker         desc->computeChecksum();
144*c8dee2aaSAndroid Build Coastguard Worker         desc->flatten(writer);
145*c8dee2aaSAndroid Build Coastguard Worker         auto data = writer.snapshotAsData();
146*c8dee2aaSAndroid Build Coastguard Worker         SkReadBuffer reader{data->data(), data->size()};
147*c8dee2aaSAndroid Build Coastguard Worker         auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
148*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, ad.has_value());
149*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, ad->getDesc()->isValid());
150*c8dee2aaSAndroid Build Coastguard Worker     }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     {  // broken header
153*c8dee2aaSAndroid Build Coastguard Worker         SkBinaryWriteBuffer writer({});
154*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);  // fChecksum
155*c8dee2aaSAndroid Build Coastguard Worker         auto data = writer.snapshotAsData();
156*c8dee2aaSAndroid Build Coastguard Worker         SkReadBuffer reader{data->data(), data->size()};
157*c8dee2aaSAndroid Build Coastguard Worker         auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
158*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, !ad.has_value());
159*c8dee2aaSAndroid Build Coastguard Worker     }
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker     {  // length too big
162*c8dee2aaSAndroid Build Coastguard Worker         SkBinaryWriteBuffer writer({});
163*c8dee2aaSAndroid Build Coastguard Worker         // Simulate a broken header
164*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);    // fChecksum
165*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(4000); // fLength
166*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);    // fCount
167*c8dee2aaSAndroid Build Coastguard Worker         auto data = writer.snapshotAsData();
168*c8dee2aaSAndroid Build Coastguard Worker         SkReadBuffer reader{data->data(), data->size()};
169*c8dee2aaSAndroid Build Coastguard Worker         auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
170*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, !ad.has_value());
171*c8dee2aaSAndroid Build Coastguard Worker     }
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     {  // length too small
174*c8dee2aaSAndroid Build Coastguard Worker         SkBinaryWriteBuffer writer({});
175*c8dee2aaSAndroid Build Coastguard Worker         // Simulate a broken header
176*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);    // fChecksum
177*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(3);    // fLength
178*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);    // fCount
179*c8dee2aaSAndroid Build Coastguard Worker         auto data = writer.snapshotAsData();
180*c8dee2aaSAndroid Build Coastguard Worker         SkReadBuffer reader{data->data(), data->size()};
181*c8dee2aaSAndroid Build Coastguard Worker         auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
182*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, !ad.has_value());
183*c8dee2aaSAndroid Build Coastguard Worker     }
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker     {  // garbage in count
186*c8dee2aaSAndroid Build Coastguard Worker         SkBinaryWriteBuffer writer({});
187*c8dee2aaSAndroid Build Coastguard Worker         // Simulate a broken header
188*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);    // fChecksum
189*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(20);   // fLength
190*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(10);   // fCount
191*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);
192*c8dee2aaSAndroid Build Coastguard Worker         writer.writeInt(0);
193*c8dee2aaSAndroid Build Coastguard Worker         auto data = writer.snapshotAsData();
194*c8dee2aaSAndroid Build Coastguard Worker         SkReadBuffer reader{data->data(), data->size()};
195*c8dee2aaSAndroid Build Coastguard Worker         auto ad = SkAutoDescriptor::MakeFromBuffer(reader);
196*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(r, !ad.has_value());
197*c8dee2aaSAndroid Build Coastguard Worker     }
198*c8dee2aaSAndroid Build Coastguard Worker }
199