Coverage Report

Created: 2026-05-24 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cms_dict_fuzzer.c
Line
Count
Source
1
/* Copyright 2023 Google LLC
2
Licensed under the Apache License, Version 2.0 (the "License");
3
you may not use this file except in compliance with the License.
4
You may obtain a copy of the License at
5
      http://www.apache.org/licenses/LICENSE-2.0
6
Unless required by applicable law or agreed to in writing, software
7
distributed under the License is distributed on an "AS IS" BASIS,
8
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
See the License for the specific language governing permissions and
10
limitations under the License.
11
*/
12
13
#include <stdint.h>
14
#include <stdlib.h>
15
#include "lcms2.h"
16
17
204
wchar_t* generateWideString(const char* characters, const uint8_t *data){
18
204
    if (!characters){
19
0
        return NULL;
20
0
    }
21
22
204
    char stringToWide[10];
23
2.04k
    for (int i = 0; i < 9; i++){
24
1.83k
        stringToWide[i] = characters[data[i] % 95];
25
1.83k
    }
26
204
    stringToWide[9] = '\0';
27
28
204
    int requiredSize = mbstowcs(NULL, stringToWide, 0);
29
204
    if (requiredSize < 0) return NULL;
30
204
    wchar_t* wideString = (wchar_t *)malloc((requiredSize + 1) * sizeof(wchar_t));
31
204
    if (!wideString) return NULL;
32
204
    mbstowcs(wideString, stringToWide, requiredSize + 1);
33
204
    return wideString;
34
204
}
35
36
77
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
37
77
    if (size < 27){
38
9
        return 0;
39
9
    }
40
41
68
    cmsContext context = cmsCreateContext(NULL, (void *)data);
42
68
    if (!context) {
43
0
        return 0;
44
0
    }
45
46
    // Create a Dictionary handle
47
68
    cmsHANDLE hDict = cmsDictAlloc(context);
48
68
    if (!hDict) {
49
0
        cmsDeleteContext(context);
50
0
        return 0;
51
0
    }
52
53
54
68
    cmsMLU *mlu = cmsMLUalloc(context, 0);
55
68
    if (!mlu) {
56
0
        cmsDictFree(hDict);
57
0
        cmsDeleteContext(context);
58
0
        return 0;
59
0
    }
60
61
68
    char* characters = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
62
68
    wchar_t* wideString = generateWideString(characters, data);
63
68
    if (!wideString) {
64
0
        cmsMLUfree(mlu);
65
0
        cmsDictFree(hDict);
66
0
        cmsDeleteContext(context);
67
0
        return 0;
68
0
    }
69
68
    cmsMLUsetWide(mlu, "en", "US", wideString);
70
68
    free(wideString);
71
72
73
68
    char ObtainedLanguage[3], ObtainedCountry[3];
74
68
    ObtainedLanguage[0] = characters[*(data+1) % 95];
75
68
    ObtainedLanguage[1] = characters[*(data+2) % 95];
76
68
    ObtainedLanguage[2] = characters[*(data) % 95];
77
78
68
    ObtainedCountry[0] = characters[*(data+2) % 95];
79
68
    ObtainedCountry[1] = characters[*data % 95];
80
68
    ObtainedCountry[2] = characters[*(data+1) % 95];
81
68
    cmsMLUgetTranslation(mlu, "en", "US",ObtainedLanguage,ObtainedCountry);
82
68
    cmsMLUtranslationsCount(mlu);
83
68
    cmsMLUtranslationsCodes(mlu, *((uint32_t *)data), ObtainedLanguage, ObtainedCountry);
84
85
68
    cmsMLU* displayName = mlu;
86
68
    cmsMLU* displayValue = mlu;
87
88
    //cmsDictAddEntry
89
68
    wchar_t* name = generateWideString(characters, data + 9);
90
68
    wchar_t* value = generateWideString(characters, data + 18);
91
68
    if (name && value) {
92
68
        cmsDictAddEntry(hDict, name, value, displayName, displayValue);
93
68
    }
94
68
    free(name);
95
68
    free(value);
96
97
    //cmsDictDup
98
68
    cmsHANDLE ResultDictDup = cmsDictDup(hDict);
99
68
    if (ResultDictDup) {
100
68
        cmsDictFree(ResultDictDup);
101
68
    }
102
    // Iterate over the Dictionary entries
103
68
    const cmsDICTentry* entry = cmsDictGetEntryList(hDict);
104
68
    cmsDictNextEntry(entry);
105
68
    cmsMLUfree(mlu);
106
68
    cmsDictFree(hDict);
107
68
    cmsDeleteContext(context);
108
68
    return 0;
109
68
}