Coverage Report

Created: 2024-05-20 07:14

/src/skia/fuzz/oss_fuzz/FuzzAndroidCodec.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2018 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/codec/SkAndroidCodec.h"
9
#include "include/core/SkBitmap.h"
10
#include "include/core/SkCanvas.h"
11
#include "include/core/SkStream.h"
12
#include "include/core/SkSurface.h"
13
#include "include/private/SkGainmapInfo.h"
14
15
#include "fuzz/Fuzz.h"
16
17
13.8k
bool FuzzAndroidCodec(const uint8_t *fuzzData, size_t fuzzSize, uint8_t sampleSize) {
18
13.8k
    auto codec = SkAndroidCodec::MakeFromStream(SkMemoryStream::MakeDirect(fuzzData, fuzzSize));
19
13.8k
    if (!codec) {
20
4.33k
        return false;
21
4.33k
    }
22
23
9.51k
    auto size = codec->getSampledDimensions(sampleSize);
24
9.51k
    auto info = SkImageInfo::MakeN32Premul(size);
25
9.51k
    SkBitmap bm;
26
9.51k
    if (!bm.tryAllocPixels(info)) {
27
        // May fail in memory-constrained fuzzing environments
28
116
        return false;
29
116
    }
30
31
9.39k
    SkAndroidCodec::AndroidOptions options;
32
9.39k
    options.fSampleSize = sampleSize;
33
34
9.39k
    auto result = codec->getAndroidPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &options);
35
9.39k
    switch (result) {
36
3.93k
        case SkCodec::kSuccess:
37
6.10k
        case SkCodec::kIncompleteInput:
38
6.53k
        case SkCodec::kErrorInInput:
39
6.53k
            break;
40
2.85k
        default:
41
2.85k
            return false;
42
9.39k
    }
43
44
6.53k
    SkGainmapInfo gainmapInfo;
45
6.53k
    auto gainmapImageStream = std::unique_ptr<SkStream>();
46
47
6.53k
    if (codec->getAndroidGainmap(&gainmapInfo, &gainmapImageStream)) {
48
        // Do something with the outputs so the compiler does not optimize the call away.
49
0
        if (!std::isfinite(gainmapInfo.fDisplayRatioSdr)) {
50
0
            return false;
51
0
        }
52
0
        if (gainmapImageStream->getLength() > 100000000) {
53
0
            return false;
54
0
        }
55
0
    }
56
57
6.53k
    auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(size.width(), size.height()));
58
6.53k
    if (!surface) {
59
        // May return nullptr in memory-constrained fuzzing environments
60
0
        return false;
61
0
    }
62
63
6.53k
    surface->getCanvas()->drawImage(bm.asImage(), 0, 0);
64
6.53k
    return true;
65
6.53k
}
66
67
#if defined(SK_BUILD_FOR_LIBFUZZER)
68
190k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
69
190k
    if (size > 10240) {
70
220
        return 0;
71
220
    }
72
190k
    Fuzz fuzz(data, size);
73
190k
    uint8_t sampleSize;
74
190k
    fuzz.nextRange(&sampleSize, 1, 64);
75
190k
    FuzzAndroidCodec(fuzz.remainingData(), fuzz.remainingSize(), sampleSize);
76
190k
    return 0;
77
190k
}
78
#endif