-
Notifications
You must be signed in to change notification settings - Fork 36
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Ran into this error at the end of fuzzing (on lcms); I believe its caused by a typedef in the generated harness.
Error:
Caused by:
Visit VarDecl, but visited Node { id: Id(0x55555667db08), kind: TypedefDecl(TypedefDecl { loc: SourceLocation { spelling_loc: Some(BareSourceLocation { offset: 3530, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 32, tok_len: 11, included_from: None, is_macro_arg_expansion: false }), expansion_loc: Some(BareSourceLocation { offset: 3530, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 32, tok_len: 11, included_from: None, is_macro_arg_expansion: false }) }, range: SourceRange { begin: SourceLocation { spelling_loc: Some(BareSourceLocation { offset: 3503, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 5, tok_len: 7, included_from: None, is_macro_arg_expansion: false }), expansion_loc: Some(BareSourceLocation { offset: 3503, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 5, tok_len: 7, included_from: None, is_macro_arg_expansion: false }) }, end: SourceLocation { spelling_loc: Some(BareSourceLocation { offset: 3633, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 135, tok_len: 1, included_from: None, is_macro_arg_expansion: false }), expansion_loc: Some(BareSourceLocation { offset: 3633, file: "/root/promptfuzz/output/lcms/succ_seeds/id_000284.cc", line: 98, presumed_file: None, presumed_line: None, col: 135, tok_len: 1, included_from: None, is_macro_arg_expansion: false }) } }, is_implicit: false, is_referenced: false, previous_decl: None, name: "CIE2000Func", type: Type { qual_type: "cmsFloat64Number (*)(const cmsCIELab *, const cmsCIELab *, cmsFloat64Number, cmsFloat64Number, cmsFloat64Number)", desugared_qual_type: None, type_alias_decl_id: None } }), inner: [Node { id: Id(0x55555667da80), kind: PointerType(PointerType { type: Type { qual_type: "cmsFloat64Number (*)(const cmsCIELab *, const cmsCIELab *, cmsFloat64Number, cmsFloat64Number, cmsFloat64Number)", desugared_qual_type: None, type_alias_decl_id: None } }), inner: [Node { id: Id(0x55555667da20), kind: Other, inner: [Node { id: Id(0x55555578c110), kind: Other, inner: [Node { id: Id(0x55555577fb10), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsFloat64Number", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x55555577fae0), kind: Other, inner: [Node { id: Id(0x555555641d70), kind: Other, inner: [] }] }] }, Node { id: Id(0x555555789ac0), kind: PointerType(PointerType { type: Type { qual_type: "const cmsCIELab *", desugared_qual_type: None, type_alias_decl_id: None } }), inner: [Node { id: Id(0x555555789671), kind: QualType(QualType { type: Type { qual_type: "const cmsCIELab", desugared_qual_type: None, type_alias_decl_id: Some(Id(0x555555780318)) }, qualifiers: "const" }), inner: [Node { id: Id(0x555555789670), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x555555789640), kind: Other, inner: [Node { id: Id(0x5555557802c0), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "struct cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: Some(Decl { id: Id(0x555555780068), kind: CXXRecordDecl, name: Some(""), type: None }) }), inner: [Node { id: Id(0x555555780100), kind: RecordType(RecordType { type: Type { qual_type: "cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, decl: Decl { id: Id(0x555555780068), kind: CXXRecordDecl, name: Some(""), type: None } }), inner: [] }] }] }] }] }] }, Node { id: Id(0x555555789ac0), kind: PointerType(PointerType { type: Type { qual_type: "const cmsCIELab *", desugared_qual_type: None, type_alias_decl_id: None } }), inner: [Node { id: Id(0x555555789671), kind: QualType(QualType { type: Type { qual_type: "const cmsCIELab", desugared_qual_type: None, type_alias_decl_id: Some(Id(0x555555780318)) }, qualifiers: "const" }), inner: [Node { id: Id(0x555555789670), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x555555789640), kind: Other, inner: [Node { id: Id(0x5555557802c0), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "struct cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: Some(Decl { id: Id(0x555555780068), kind: CXXRecordDecl, name: Some(""), type: None }) }), inner: [Node { id: Id(0x555555780100), kind: RecordType(RecordType { type: Type { qual_type: "cmsCIELab", desugared_qual_type: None, type_alias_decl_id: None }, decl: Decl { id: Id(0x555555780068), kind: CXXRecordDecl, name: Some(""), type: None } }), inner: [] }] }] }] }] }] }, Node { id: Id(0x55555577fb10), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsFloat64Number", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x55555577fae0), kind: Other, inner: [Node { id: Id(0x555555641d70), kind: Other, inner: [] }] }] }, Node { id: Id(0x55555577fb10), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsFloat64Number", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x55555577fae0), kind: Other, inner: [Node { id: Id(0x555555641d70), kind: Other, inner: [] }] }] }, Node { id: Id(0x55555577fb10), kind: ElaboratedType(ElaboratedType { type: Type { qual_type: "cmsFloat64Number", desugared_qual_type: None, type_alias_decl_id: None }, owned_tag_decl: None }), inner: [Node { id: Id(0x55555577fae0), kind: Other, inner: [Node { id: Id(0x555555641d70), kind: Other, inner: [] }] }] }] }] }] }] }
Location:
src/analysis/dfa.rs:194:9
id_000284.cc:
#include <lcms2.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <vector>
#include <fstream>
#include <iostream>
#include <sstream>
//<ID> 284
//<Prompt> []
/*<Combination>: [
*/
//<score> 0, nr_unique_branch: 0
//<Quality> {"density":0,"unique_branches":{},"library_calls":[],"critical_calls":[],"visited":0}
/*Certainly! Let’s devise an event using those APIs and your byte-stream input, then implement the `LLVMFuzzerTestOneInput` for you.
---
### **Step 1: Event Description**
Given a byte-stream of lcms "output data" (which could be an IT8 text table, or encoded color patches, etc.), we can:
1. **Use a Plugin** (cmsPluginTHR) to optionally extend/modify lcms behavior.
2. **Create an sRGB profile** (cmsCreate_sRGBProfile).
3. **Create a custom RGB profile** with decoded white point, primaries, and tone curves (cmsCreateRGBProfile).
4. **Open the input as an IT8 table** using the IT8 parser (simulated by using a handle: see related APIs such as cmsIT8LoadFromFile, but here, we use the patch querying function).
5. **Attempt to read a patch from the IT8 handle by name** (cmsIT8GetPatchByName).
6. **Build two Lab color values from input, calculate their difference using CIE2000DeltaE** (cmsCIE2000DeltaE).
---
### **Step 2: Implementation Plan**
- Use the input as both profile creation parameter and plugin data.
- Use part of input as a "patch name" when querying IT8.
- Use part of input as Lab values.
- **Resource cleanup:** Profiles, IT8 handle, tone curves.
---
### **Step 3: C++ Fuzzer Implementation**
*/
// Helper to extract floating point value from data, advances offset safely
static double extract_double(const uint8_t *data, size_t size, size_t &offset) {
if (offset + sizeof(double) > size) return 0.0;
double val;
memcpy(&val, data + offset, sizeof(double));
offset += sizeof(double);
return val;
}
// Helper to extract null-terminated patch name
static void extract_patch_name(const uint8_t *data, size_t size, size_t &offset, char *out, size_t max_len) {
size_t remain = size > offset ? size - offset : 0;
size_t to_copy = remain < max_len-1 ? remain : max_len-1;
memcpy(out, data + offset, to_copy);
out[to_copy] = '\0';
offset += to_copy;
}
// Fuzz driver
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 128) return 0; // Require some minimum input
size_t offset = 0;
// 1. Use part of input as plugin data
size_t plugin_len = size > 32 ? 32 : size; // up to 32 bytes
void *plugin_data = malloc(plugin_len);
if (!plugin_data) return 0;
memcpy(plugin_data, data, plugin_len);
cmsContext ctx = nullptr;
cmsPluginTHR(ctx, plugin_data);
offset += plugin_len;
// 2. Create an sRGB profile from the library
cmsHPROFILE hSRGB = cmsCreate_sRGBProfile();
// 3. Prepare Lab values from fuzzer input (6 doubles needed)
cmsCIELab lab1, lab2;
lab1.L = extract_double(data, size, offset);
lab1.a = extract_double(data, size, offset);
lab1.b = extract_double(data, size, offset);
lab2.L = extract_double(data, size, offset);
lab2.a = extract_double(data, size, offset);
lab2.b = extract_double(data, size, offset);
// 4. Compute DeltaE 2000 using fuzzer-provided coefficients
double Kl = extract_double(data, size, offset);
double Kc = extract_double(data, size, offset);
double Kh = extract_double(data, size, offset);
cmsFloat64Number delta_e = 0.0;
typedef cmsFloat64Number (*CIE2000Func)(const cmsCIELab *, const cmsCIELab *, cmsFloat64Number, cmsFloat64Number, cmsFloat64Number);
// Use dlsym or manual binding if not directly declared in header
// For this exercise, we simulate as if it's available in lcms2.h as cmsCIE2000DeltaE
#ifdef cmsCIE2000DeltaE
delta_e = cmsCIE2000DeltaE(&lab1, &lab2, Kl, Kc, Kh);
#endif
(void)delta_e; // suppress unused warning
// 5. Create a custom RGB profile
cmsCIExyY wp;
wp.x = extract_double(data, size, offset);
wp.y = extract_double(data, size, offset);
wp.Y = extract_double(data, size, offset);
cmsCIExyYTRIPLE primaries;
primaries.Red.x = extract_double(data, size, offset);
primaries.Red.y = extract_double(data, size, offset);
primaries.Red.Y = extract_double(data, size, offset);
primaries.Green.x = extract_double(data, size, offset);
primaries.Green.y = extract_double(data, size, offset);
primaries.Green.Y = extract_double(data, size, offset);
primaries.Blue.x = extract_double(data, size, offset);
primaries.Blue.y = extract_double(data, size, offset);
primaries.Blue.Y = extract_double(data, size, offset);
// Tone curves: three curves, use a simple parametric segment
cmsToneCurve* curves[3] = {nullptr, nullptr, nullptr};
for (int i = 0; i < 3; ++i) {
cmsFloat32Number values[2];
values[0] = static_cast<cmsFloat32Number>(extract_double(data, size, offset));
values[1] = static_cast<cmsFloat32Number>(extract_double(data, size, offset));
curves[i] = cmsBuildTabulatedToneCurveFloat(ctx, 2, values);
}
cmsHPROFILE hRGB = cmsCreateRGBProfile(&wp, &primaries, curves);
// Release tone curves
for (int i = 0; i < 3; ++i)
if (curves[i]) cmsFreeToneCurve(curves[i]);
// 6. IT8 table handling: treat input data as possible IT8 table
FILE *in_file = fmemopen((void*)data, size, "rb");
cmsHANDLE hIT8 = nullptr;
if (in_file) {
hIT8 = cmsIT8LoadFromFile(ctx, "input_file");
// Actually IT8LoadFromFile expects a file name, but for fuzzing, we assume it may pick up the right path from the fmemopen.
}
// 7. From input, extract a patch name and query the IT8 handle
char patch_name[32];
extract_patch_name(data, size, offset, patch_name, sizeof(patch_name));
if (hIT8 && patch_name[0] != '\0') {
cmsIT8GetPatchByName(hIT8, patch_name);
}
// Cleanup
if (hIT8) cmsIT8Free(hIT8); // If available; not in your list, but must be in the IT8 API
if (in_file) fclose(in_file);
if (hRGB) cmsCloseProfile(hRGB);
if (hSRGB) cmsCloseProfile(hSRGB);
free(plugin_data);
return 0;
}Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working