Coverage Report

Created: 2024-05-20 07:14

/src/skia/fuzz/oss_fuzz/FuzzCOLRv1.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2022 Google, LLC
3
 *
4
 * Use of this source code is governed by a BSD-style license that can be
5
 * found in the LICENSE file.
6
 */
7
8
#include "include/core/SkCanvas.h"
9
#include "include/core/SkData.h"
10
#include "include/core/SkFont.h"
11
#include "include/core/SkFontMgr.h"
12
#include "include/core/SkStream.h"
13
#include "include/core/SkSurface.h"
14
#include "include/core/SkTypeface.h"
15
#include "tools/fonts/FontToolUtils.h"
16
17
#include <algorithm>
18
19
5.14k
void FuzzCOLRv1(const uint8_t* data, size_t size) {
20
    // We do not want the portable fontmgr here, as it does not allow creation of fonts from bytes.
21
5.14k
    sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
22
5.14k
    std::unique_ptr<SkStreamAsset> stream = SkMemoryStream::MakeDirect(data, size);
23
5.14k
    sk_sp<SkTypeface> typeface = mgr->makeFromStream(std::move(stream), 0);
24
25
5.14k
    if (!typeface) {
26
1.03k
        return;
27
1.03k
    }
28
29
4.10k
    auto s = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(128, 128));
30
4.10k
    if (!s) {
31
0
        return;
32
0
    }
33
34
    // Place at a baseline in the lower part of the canvas square, but canvas size and baseline
35
    // placement are chosen arbitrarily and we just need to cover colrv1 rendering in this
36
    // fuzz test.
37
4.10k
    SkFont colrv1Font = SkFont(typeface, 120);
38
4.10k
    SkCanvas* canvas = s->getCanvas();
39
4.10k
    SkPaint paint;
40
4.10k
    int numGlyphs = typeface->countGlyphs();
41
42
31.9k
    for (int i = 0; i < std::min(numGlyphs, 10); ++i) {
43
27.8k
        SkPoint origin = SkPoint::Make(10, 108);
44
27.8k
        SkPoint position = SkPoint::Make(0, 0);
45
27.8k
        SkGlyphID glyphId = i;
46
27.8k
        canvas->drawGlyphs(1, &glyphId, &position, origin, colrv1Font, paint);
47
27.8k
    }
48
4.10k
}
49
50
#if defined(SK_BUILD_FOR_LIBFUZZER)
51
190k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
52
    // COLRv1 corpus file sizes range from 8k for a small test glyph file to about 80k covering
53
    // most of the complex Noto Emoji glyphs, compare:
54
    // See https://github.com/googlefonts/color-fonts/blob/main/rebuild_fuzzer_corpus.py
55
190k
    if (size > 80 * 1024) {
56
220
        return 0;
57
220
    }
58
190k
    FuzzCOLRv1(data, size);
59
190k
    return 0;
60
190k
}
61
#endif