Coverage Report

Created: 2024-09-14 07:19

/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
3.30k
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
3.30k
    sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
22
3.30k
    std::unique_ptr<SkStreamAsset> stream = SkMemoryStream::MakeDirect(data, size);
23
3.30k
    sk_sp<SkTypeface> typeface = mgr->makeFromStream(std::move(stream), 0);
24
25
3.30k
    if (!typeface) {
26
667
        return;
27
667
    }
28
29
2.63k
    auto s = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(128, 128));
30
2.63k
    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
2.63k
    SkFont colrv1Font = SkFont(typeface, 120);
38
2.63k
    SkCanvas* canvas = s->getCanvas();
39
2.63k
    SkPaint paint;
40
2.63k
    int numGlyphs = typeface->countGlyphs();
41
42
20.8k
    for (int i = 0; i < std::min(numGlyphs, 10); ++i) {
43
18.2k
        SkPoint origin = SkPoint::Make(10, 108);
44
18.2k
        SkPoint position = SkPoint::Make(0, 0);
45
18.2k
        SkGlyphID glyphId = i;
46
18.2k
        canvas->drawGlyphs(1, &glyphId, &position, origin, colrv1Font, paint);
47
18.2k
    }
48
2.63k
}
49
50
#if defined(SK_BUILD_FOR_LIBFUZZER)
51
162k
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
162k
    if (size > 80 * 1024) {
56
207
        return 0;
57
207
    }
58
162k
    FuzzCOLRv1(data, size);
59
162k
    return 0;
60
162k
}
61
#endif