1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
9cb93a386Sopenharmony_ci#include "src/core/SkDescriptor.h"
10cb93a386Sopenharmony_ci#include "src/core/SkScalerContext.h"
11cb93a386Sopenharmony_ci#include "tests/Test.h"
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci#include <memory>
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ciclass SkDescriptorTestHelper {
16cb93a386Sopenharmony_cipublic:
17cb93a386Sopenharmony_ci    static void SetLength(SkDescriptor* desc, size_t length) { desc->fLength = length; }
18cb93a386Sopenharmony_ci    static void SetCount(SkDescriptor* desc, uint32_t count) { desc->fCount = count; }
19cb93a386Sopenharmony_ci};
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_ciDEF_TEST(Descriptor_empty, r) {
22cb93a386Sopenharmony_ci    const size_t size = sizeof(SkDescriptor);
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
25cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->isValid());
26cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->getLength() == size);
27cb93a386Sopenharmony_ci}
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ciDEF_TEST(Descriptor_valid_simple, r) {
30cb93a386Sopenharmony_ci    const size_t size =
31cb93a386Sopenharmony_ci            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);
32cb93a386Sopenharmony_ci
33cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
34cb93a386Sopenharmony_ci    SkScalerContextRec rec;
35cb93a386Sopenharmony_ci    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
36cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->isValid());
37cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->getLength() == size);
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
40cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
41cb93a386Sopenharmony_ci}
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ciDEF_TEST(Descriptor_valid_simple_extra_space, r) {
44cb93a386Sopenharmony_ci    const size_t extra_space = 100;
45cb93a386Sopenharmony_ci    const size_t size =
46cb93a386Sopenharmony_ci            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec);
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size + extra_space);
49cb93a386Sopenharmony_ci    SkScalerContextRec rec;
50cb93a386Sopenharmony_ci    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
51cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->isValid());
52cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->getLength() == size);
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
55cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
56cb93a386Sopenharmony_ci}
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ciDEF_TEST(Descriptor_valid_more_tags, r) {
59cb93a386Sopenharmony_ci    const size_t effectSize = 16;
60cb93a386Sopenharmony_ci    const size_t testSize = 32;
61cb93a386Sopenharmony_ci    const size_t size = sizeof(SkDescriptor) + 3 * sizeof(SkDescriptor::Entry) +
62cb93a386Sopenharmony_ci                        sizeof(SkScalerContextRec) + effectSize + testSize;
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
65cb93a386Sopenharmony_ci    SkScalerContextRec rec;
66cb93a386Sopenharmony_ci    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
67cb93a386Sopenharmony_ci    desc->addEntry(kEffects_SkDescriptorTag, effectSize, nullptr);
68cb93a386Sopenharmony_ci    desc->addEntry(SkSetFourByteTag('t', 'e', 's', 't'), testSize, nullptr);
69cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->isValid());
70cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->getLength() == size);
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size - 4);
73cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
74cb93a386Sopenharmony_ci}
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ciDEF_TEST(Descriptor_invalid_rec_size, r) {
77cb93a386Sopenharmony_ci    const size_t size =
78cb93a386Sopenharmony_ci            sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) - 4;
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
81cb93a386Sopenharmony_ci    SkScalerContextRec rec;
82cb93a386Sopenharmony_ci    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec) - 4, &rec);
83cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->getLength() == size);
84cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
85cb93a386Sopenharmony_ci}
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ciDEF_TEST(Descriptor_invalid_length, r) {
88cb93a386Sopenharmony_ci    const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);
89cb93a386Sopenharmony_ci    const size_t effect_size = 1000;
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
92cb93a386Sopenharmony_ci    desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size);
95cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size + effect_size);
98cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, desc->isValid());
99cb93a386Sopenharmony_ci}
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ciDEF_TEST(Descriptor_entry_too_big, r) {
102cb93a386Sopenharmony_ci    const size_t size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry) + 4;
103cb93a386Sopenharmony_ci    // Must be less than fLength, but big enough to be bigger then fLength when added.
104cb93a386Sopenharmony_ci    const size_t effect_size = sizeof(SkDescriptor) + sizeof(SkDescriptor::Entry);
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(size);
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_ci    desc->addEntry(kEffects_SkDescriptorTag, effect_size, nullptr);
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size);
111cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetCount(desc.get(), 2);
112cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), size);
115cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetCount(desc.get(), 1);
116cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
117cb93a386Sopenharmony_ci}
118cb93a386Sopenharmony_ci
119cb93a386Sopenharmony_ciDEF_TEST(Descriptor_entry_over_end, r) {
120cb93a386Sopenharmony_ci    auto desc = SkDescriptor::Alloc(36);
121cb93a386Sopenharmony_ci
122cb93a386Sopenharmony_ci    // Make the start of the Entry be in the SkDescriptor, but the second half falls out side the
123cb93a386Sopenharmony_ci    // SkDescriptor. So: 12 (for descriptor) + 8 (for entry) + 12 (for entry length) = 32. An
124cb93a386Sopenharmony_ci    // An Entry is 8 bytes, so 4 bytes are < 36 and 4 bytes > 36.
125cb93a386Sopenharmony_ci    desc->addEntry(kEffects_SkDescriptorTag, 12, nullptr);
126cb93a386Sopenharmony_ci
127cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetLength(desc.get(), 36);
128cb93a386Sopenharmony_ci    SkDescriptorTestHelper::SetCount(desc.get(), 2);
129cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, !desc->isValid());
130cb93a386Sopenharmony_ci}
131