Skip to content

Commit

Permalink
lcms: simplify universal fuzzer (google#9099)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidKorczynski authored and eamonnmcmanus committed Mar 15, 2023
1 parent b496413 commit a12aa0a
Showing 1 changed file with 20 additions and 115 deletions.
135 changes: 20 additions & 115 deletions projects/lcms/cms_universal_transform_fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,120 +14,25 @@ limitations under the License.
#include "lcms2.h"


/* Fuzzer that creates a transform with the following vars initialized by way
* of fuzzer data:
* - srcFormat
* - dstFormat
* - profile
* Then applies the transform once on a input derived from the fuzzer.
* This input data and output data to cmsDoTransform is allocated such
* that it is large enough for any input/output types.
*/
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 4096) {
return 0;
}
uint8_t *profile_data = NULL;
uint8_t *input_data = NULL;
uint8_t *output_data = NULL;

// Create a random src and dst format
uint32_t srcFormat = *(uint32_t*)data;
data += 4;
size -= 4;
uint32_t dstFormat = *(uint32_t*)data;
data += 4;
size -= 4;
uint32_t flags = *(uint32_t*)data;
data += 4;
size -= 4;
uint32_t intent = (*(uint32_t*)data) % 16;
data += 4;
size -= 4;

if (T_CHANNELS(srcFormat) <= 0 ||
T_EXTRA(srcFormat) > 5 ||
T_CHANNELS(dstFormat) == 0) {
return 0;
}
int max_channels = T_CHANNELS(dstFormat);
if (max_channels < T_CHANNELS(srcFormat)) {
max_channels = T_CHANNELS(srcFormat);
}

profile_data = (uint8_t*)malloc(512);
memcpy(profile_data, data, 512);
data += 512;
size -= 512;
cmsHPROFILE srcProfile = cmsOpenProfileFromMem(profile_data, 512);
if (!srcProfile) {
goto cleanup;
}

cmsHPROFILE dstProfile = cmsCreate_sRGBProfile();
if (!dstProfile) {
cmsCloseProfile(srcProfile);
goto cleanup;
}

cmsColorSpaceSignature srcCS = cmsGetColorSpace(srcProfile);
cmsUInt32Number nSrcComponents = cmsChannelsOf(srcCS);

// allocate input buffer with fuzz data. Choose a large enough size so
// overflows wont occur due to erroneous typing.
int pixel_size = T_BYTES(srcFormat);
if (pixel_size < T_BYTES(dstFormat))
pixel_size = T_BYTES(dstFormat);
if (pixel_size == 0)
pixel_size = sizeof(uint64_t);

// Ensure inout_size meets the upper bound of input and output
// buffers.
int inout_size = 4 + nSrcComponents;
if (max_channels > 0) {
inout_size *= max_channels;
}
if (T_EXTRA(srcFormat) > 0) {
inout_size *= T_EXTRA(srcFormat);
}
if (pixel_size > 0) {
inout_size *= pixel_size;
}
inout_size *= 80;
if (size < inout_size) {
cmsCloseProfile(srcProfile);
cmsCloseProfile(dstProfile);
goto cleanup;
}

input_data = (uint8_t *)malloc(inout_size);
memcpy(input_data, data, inout_size);
// Make empty output data
output_data = (uint8_t *)malloc(inout_size);

cmsHTRANSFORM hTransform = cmsCreateTransform(
srcProfile, srcFormat, dstProfile, dstFormat, intent, flags);
cmsCloseProfile(srcProfile);
cmsCloseProfile(dstProfile);

if (!hTransform) {
goto cleanup;
}

// Do the transform
cmsDoTransform(hTransform, input_data, output_data, 1);
cmsDeleteTransform(hTransform);

cleanup:
if (output_data != NULL) {
free(output_data);
}
if (input_data != NULL) {
free(input_data);
}
if (profile_data != NULL) {
free(profile_data);
}

return 0;
if (size < 2) {
return 0;
}

size_t mid = size / 2;

cmsHPROFILE hInProfile, hOutProfile;
cmsHTRANSFORM hTransform;

hInProfile = cmsOpenProfileFromMem(data, mid);
hOutProfile = cmsOpenProfileFromMem(data + mid, size - mid);
hTransform = cmsCreateTransform(hInProfile, TYPE_BGR_8, hOutProfile,
TYPE_BGR_8, INTENT_PERCEPTUAL, 0);
cmsCloseProfile(hInProfile);
cmsCloseProfile(hOutProfile);

if (hTransform) {
cmsDeleteTransform(hTransform);
}
return 0;
}

0 comments on commit a12aa0a

Please sign in to comment.