You are a security testing engineer who wants to write a C++ program to execute all lines in a given function by defining and initialising its parameters in a suitable way before fuzzing the function through `LLVMFuzzerTestOneInput`. Carefully study the function signature and its parameters, then follow the example problems and solutions to answer the final problem. YOU MUST call the function to fuzz in the solution. Try as many variations of these inputs as possible. Do not use a random number generator such as `rand()`. All variables used MUST be declared and initialized. Carefully make sure that the variable and argument types in your code match and compiles successfully. Add type casts to make types match. Do not create new variables with the same names as existing variables. WRONG: ``` int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { void* data = Foo(); } ``` EXTREMELY IMPORTANT: If you write code using `goto`, you MUST MUST also declare all variables BEFORE the `goto`. Never introduce new variables after the `goto`. WRONG: ``` int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int a = bar(); if (!some_function()) goto EXIT; Foo b = target_function(data, size); int c = another_func(); EXIT: return 0; } ``` CORRECT: ``` int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int a = bar(); Foo b; int c; if (!some_function()) goto EXIT; b = target_function(data, size); c = another_func() EXIT: return 0; } ``` If an example provided for the same library includes a unique header file, then it must be included in the solution as well. Problem: ``` CJSON_PUBLIC(void) cJSON_Minify(char *json) ``` Solution: ``` #include #include #include #ifdef __cplusplus extern "C" { #endif #include "../cJSON.h" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); /* required by C89 */ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { cJSON *json; size_t offset = 4; unsigned char *copied; char *printed_json = NULL; int minify, require_termination, formatted, buffered; if(size <= offset) return 0; if(data[size-1] != '\0') return 0; if(data[0] != '1' && data[0] != '0') return 0; if(data[1] != '1' && data[1] != '0') return 0; if(data[2] != '1' && data[2] != '0') return 0; if(data[3] != '1' && data[3] != '0') return 0; minify = data[0] == '1' ? 1 : 0; require_termination = data[1] == '1' ? 1 : 0; formatted = data[2] == '1' ? 1 : 0; buffered = data[3] == '1' ? 1 : 0; json = cJSON_ParseWithOpts((const char*)data + offset, NULL, require_termination); if(json == NULL) return 0; if(buffered) { printed_json = cJSON_PrintBuffered(json, 1, formatted); } else { /* unbuffered printing */ if(formatted) { printed_json = cJSON_Print(json); } else { printed_json = cJSON_PrintUnformatted(json); } } if(printed_json != NULL) free(printed_json); if(minify) { copied = (unsigned char*)malloc(size); if(copied == NULL) return 0; memcpy(copied, data, size); cJSON_Minify((char*)copied + offset); free(copied); } cJSON_Delete(json); return 0; } #ifdef __cplusplus } #endif ``` Problem: ``` BGD_DECLARE(void) gdImageString (gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color) ``` Solution: ``` #include #include #include #include #include #include "gd.h" #include "gdfontg.h" #include "gdfontl.h" #include "gdfontmb.h" #include "gdfonts.h" #include "gdfontt.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider stream(data, size); const uint8_t slate_width = stream.ConsumeIntegral(); const uint8_t slate_height = stream.ConsumeIntegral(); gdImagePtr slate_image = gdImageCreateTrueColor(slate_width, slate_height); if (slate_image == nullptr) { return 0; } const int x_position = stream.ConsumeIntegral(); const int y_position = stream.ConsumeIntegral(); const int text_color = stream.ConsumeIntegral(); const gdFontPtr font_ptr = stream.PickValueInArray( {gdFontGetGiant(), gdFontGetLarge(), gdFontGetMediumBold(), gdFontGetSmall(), gdFontGetTiny()}); const std::string text = stream.ConsumeRemainingBytesAsString(); gdImageString(slate_image, font_ptr, x_position, y_position, reinterpret_cast(const_cast(text.c_str())), text_color); gdImageDestroy(slate_image); return 0; } ``` Problem: ``` MPG123_EXPORT int mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done ) ``` Solution: ``` #include #include #include #include #include #include #include "mpg123.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { static bool initialized = false; if (!initialized) { mpg123_init(); initialized = true; } int ret; mpg123_handle* handle = mpg123_new(nullptr, &ret); if (handle == nullptr) { return 0; } ret = mpg123_param(handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.); if(ret == MPG123_OK) ret = mpg123_open_feed(handle); if (ret != MPG123_OK) { mpg123_delete(handle); return 0; } std::vector output_buffer(mpg123_outblock(handle)); size_t output_written = 0; // Initially, start by feeding the decoder more data. int decode_ret = MPG123_NEED_MORE; FuzzedDataProvider provider(data, size); while ((decode_ret != MPG123_ERR)) { if (decode_ret == MPG123_NEED_MORE) { if (provider.remaining_bytes() == 0 || mpg123_tellframe(handle) > 10000 || mpg123_tell_stream(handle) > 1<<20) { break; } const size_t next_size = provider.ConsumeIntegralInRange( 0, provider.remaining_bytes()); auto next_input = provider.ConsumeBytes(next_size); decode_ret = mpg123_decode(handle, next_input.data(), next_input.size(), output_buffer.data(), output_buffer.size(), &output_written); } else if (decode_ret != MPG123_ERR && decode_ret != MPG123_NEED_MORE) { decode_ret = mpg123_decode(handle, nullptr, 0, output_buffer.data(), output_buffer.size(), &output_written); } else { // Unhandled mpg123_decode return value. abort(); } } mpg123_delete(handle); return 0; } ``` You MUST call `CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)` in your solution! Problem: ``` CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) ``` Solution: