Coverage Report

Created: 2026-04-03 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cms_profile_fuzzer.c
Line
Count
Source
1
/* Copyright 2022 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 <assert.h>
15
#include <stdlib.h>
16
#include <unistd.h>
17
18
#include "lcms2.h"
19
20
cmsTagSignature tagsToRead[] = {
21
  cmsSigGreenColorantTag,
22
  cmsSigGreenMatrixColumnTag,
23
  cmsSigGreenTRCTag,
24
  cmsSigMeasurementTag,
25
  cmsSigNamedColorTag,
26
  cmsSigPreview1Tag,
27
  cmsSigPs2CRD2Tag,
28
  cmsSigPs2CRD3Tag,
29
  cmsSigRedTRCTag,
30
};
31
32
3.35k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
33
3.35k
  if (size == 0)
34
0
    return 0;
35
36
3.35k
  char filename[256];
37
3.35k
  sprintf(filename, "/tmp/libfuzzer.%d.icc", getpid());
38
3.35k
  FILE *fp = fopen(filename, "wb");
39
3.35k
  if (!fp) {
40
0
    return 0;
41
0
  }
42
3.35k
  fwrite(data, size, 1, fp);
43
3.35k
  fclose(fp);
44
45
3.35k
  cmsHPROFILE hProfile = cmsOpenProfileFromFile(filename, "r");
46
  // If we have a profile, perform a set of operations
47
3.35k
  if (hProfile) {
48
2.42k
    char tagBuffer[4];
49
50
    // Perform multiple tag reads. Read tags twice as behavior matters
51
    // if tags have been read before.
52
7.28k
    for (int j = 0; j < 2; j++) {
53
48.5k
      for (int i = 0; i < sizeof(tagsToRead)/sizeof(tagsToRead[0]); i++) {
54
43.6k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
55
43.6k
        cmsReadRawTag(hProfile, tagsToRead[i], NULL, 0);
56
43.6k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
57
43.6k
        cmsReadTag(hProfile, tagsToRead[i]);
58
43.6k
      }
59
4.85k
    }
60
61
    // Read profile info
62
2.42k
    cmsInfoType info = data[0] % 4;
63
2.42k
    char outBuffer[100];
64
65
2.42k
    cmsGetProfileInfoASCII(hProfile, info, "DEN", "DEN", outBuffer, 100);
66
2.42k
    cmsGetTagCount(hProfile);
67
2.42k
    if (size > 2) {
68
2.42k
      cmsGetTagSignature(hProfile, (cmsUInt32Number)data[1]);
69
2.42k
    }
70
2.42k
    if (size > 40) {
71
2.42k
      cmsTagSignature tag = *((uint32_t *)(data+5));
72
2.42k
      cmsTagLinkedTo(hProfile, tag);
73
2.42k
    }
74
75
    // Save to random file
76
2.42k
    cmsSaveProfileToFile(hProfile, "random.icc");
77
2.42k
    cmsCloseProfile(hProfile);
78
2.42k
  }
79
80
  // Let's write the profile now.
81
3.35k
  hProfile = cmsOpenProfileFromFile(filename, "w");
82
3.35k
  if (hProfile) {
83
3.35k
    char tagBuffer[4] = {'a', 'a', 'a', 'a'};
84
85
    // Perform multiple tag reads
86
10.0k
    for (int j = 0; j < 2; j++) {
87
67.1k
      for (int i = 0; i < sizeof(tagsToRead)/sizeof(tagsToRead[0]); i++) {
88
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
89
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], NULL, 0);
90
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
91
60.4k
        cmsReadTag(hProfile, tagsToRead[i]);
92
60.4k
      }
93
6.71k
    }
94
95
33.5k
    for (int i = 0; i < sizeof(tagsToRead)/sizeof(tagsToRead[0]); i++) {
96
30.2k
      cmsWriteRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
97
30.2k
    }
98
99
10.0k
    for (int j = 0; j < 2; j++) {
100
67.1k
      for (int i = 0; i < sizeof(tagsToRead)/sizeof(tagsToRead[0]); i++) {
101
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
102
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], NULL, 0);
103
60.4k
        cmsReadRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
104
60.4k
        cmsReadTag(hProfile, tagsToRead[i]);
105
60.4k
      }
106
6.71k
    }
107
108
33.5k
    for (int i = 0; i < sizeof(tagsToRead)/sizeof(tagsToRead[0]); i++) {
109
30.2k
      cmsWriteRawTag(hProfile, tagsToRead[i], tagBuffer, 4);
110
30.2k
    }
111
112
    // Save to random file
113
3.35k
    cmsSaveProfileToFile(hProfile, "random.icc");
114
3.35k
    cmsCloseProfile(hProfile);
115
3.35k
  }
116
117
3.35k
  unlink(filename);
118
3.35k
  return 0;
119
3.35k
}