THRIFT-5855: Add c_glib fuzzers

Add fuzzers for c_glib support, to improve the reliability/robustness of the implementation
diff --git a/FUZZING.md b/FUZZING.md
index f0f0324..b3e0c15 100644
--- a/FUZZING.md
+++ b/FUZZING.md
@@ -16,10 +16,10 @@
 We currently maintain fuzzers for the following languages:
 
 - Go (needs improvement)
+- c_glib (partially supported, needs round-trip support)
 
 We are working on adding fuzzers for the following languages:
 
-- c_glib
 - C++
 - Rust  
 - Swift
diff --git a/configure.ac b/configure.ac
index c8c740c..8147a0b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -780,6 +780,7 @@
   lib/c_glib/Makefile
   lib/c_glib/thrift_c_glib.pc
   lib/c_glib/test/Makefile
+  lib/c_glib/test/fuzz/Makefile
   lib/d/Makefile
   lib/d/test/Makefile
   lib/erl/Makefile
diff --git a/lib/c_glib/test/Makefile.am b/lib/c_glib/test/Makefile.am
index 6eeece9..e61f875 100644
--- a/lib/c_glib/test/Makefile.am
+++ b/lib/c_glib/test/Makefile.am
@@ -18,7 +18,7 @@
 #
 AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
 
-SUBDIRS =
+SUBDIRS = fuzz
 
 BUILT_SOURCES = \
         gen-c_glib/t_test_container_test_types.c \
diff --git a/lib/c_glib/test/fuzz/Makefile.am b/lib/c_glib/test/fuzz/Makefile.am
new file mode 100644
index 0000000..e7d0e35
--- /dev/null
+++ b/lib/c_glib/test/fuzz/Makefile.am
@@ -0,0 +1,66 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
+
+BUILT_SOURCES = \
+    gen-c_glib/fuzz_test_no_uuid_types.h \
+    gen-c_glib/fuzz_test_no_uuid_types.c
+
+noinst_LTLIBRARIES = libtestgencfuzz.la
+nodist_libtestgencfuzz_la_SOURCES = \
+    gen-c_glib/fuzz_test_no_uuid_types.c \
+    gen-c_glib/fuzz_test_no_uuid_types.h
+
+libtestgencfuzz_la_LIBADD = $(top_builddir)/lib/c_glib/libthrift_c_glib.la
+
+AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir)
+AM_CFLAGS = -g $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) -I$(top_srcdir)/lib/c_glib/src -I../gen-c_glib -I./gen-c_glib -I$(top_builddir)
+AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS)
+
+if USING_CLANG
+AM_LDFLAGS += -fsanitize=fuzzer
+endif
+
+check_PROGRAMS = fuzz_parse_compact fuzz_parse_binary
+
+fuzz_parse_compact_SOURCES = fuzz_parse_compact.c
+fuzz_parse_compact_LDADD = \
+    libtestgencfuzz.la \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o
+
+fuzz_parse_binary_SOURCES = fuzz_parse_binary.c
+fuzz_parse_binary_LDADD = \
+    libtestgencfuzz.la \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/protocol/libthrift_c_glib_la-thrift_protocol.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o
+
+#
+# Common thrift code generation rules
+#
+gen-c_glib/fuzz_test_no_uuid_types.c gen-c_glib/fuzz_test_no_uuid_types.h: $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift
+	$(THRIFT) --gen c_glib -r $<
+
+clean-local:
+	$(RM) -r gen-c_glib/
+	$(RM) *.o
+	$(RM) libtestgencfuzz.la 
\ No newline at end of file
diff --git a/lib/c_glib/test/fuzz/README.md b/lib/c_glib/test/fuzz/README.md
new file mode 100644
index 0000000..d1a100e
--- /dev/null
+++ b/lib/c_glib/test/fuzz/README.md
@@ -0,0 +1,20 @@
+# C GLib Fuzzing README
+
+To build the fuzz targets, run `make check` in this directory. The build system uses LLVM's libFuzzer for fuzzing the C GLib Thrift implementation.
+
+These are standard libFuzzer targets, so you can run them using the standard libFuzzer interface. After building, you can run a fuzzer using:
+```bash
+./<fuzzer_name>
+```
+
+We currently have two fuzz targets:
+
+* fuzz_parse_binary -- fuzzes the deserialization of the Binary protocol
+* fuzz_parse_compact -- fuzzes the deserialization of the Compact protocol
+* TODO: Add round trip fuzzers, similar to other languages.
+
+The fuzzers use libFuzzer's built-in mutation engine to generate test cases. Each fuzzer implements the standard `LLVMFuzzerTestOneInput` interface.
+
+For more information about libFuzzer and its options, see the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html).
+
+You can also use the corpus generator from the Rust implementation to generate initial corpus files that can be used with these C GLib fuzzers, since the wire formats are identical between implementations.
diff --git a/lib/c_glib/test/fuzz/fuzz_parse_binary.c b/lib/c_glib/test/fuzz/fuzz_parse_binary.c
new file mode 100644
index 0000000..25b9fe0
--- /dev/null
+++ b/lib/c_glib/test/fuzz/fuzz_parse_binary.c
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/transport/thrift_memory_buffer.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/thrift_configuration.h>
+#include <stdint.h>
+#include "gen-c_glib/fuzz_test_no_uuid_types.h"
+#include <stdio.h>
+
+// 10MB message size limit to prevent over-allocation during fuzzing
+#define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024)
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  GError* error = NULL;
+  
+  // Create a GByteArray with the fuzz data
+  GByteArray* byte_array = g_byte_array_new();
+  g_byte_array_append(byte_array, data, size);
+
+  // Create a ThriftConfiguration with message size limits
+  ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, 
+                                                     "max_message_size", FUZZ_MAX_MESSAGE_SIZE,
+                                                     "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, 
+                                                     NULL);
+
+  // Create a memory buffer transport with the byte array and configuration
+  ThriftTransport* transport = THRIFT_TRANSPORT(
+      g_object_new(THRIFT_TYPE_MEMORY_BUFFER,
+                  "buf", byte_array,
+                  "buf_size", size,
+                  "configuration", tconfiguration,
+                  NULL));
+
+  // Create a binary protocol
+  ThriftProtocol* protocol = THRIFT_PROTOCOL(
+      g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, 
+                  "transport", transport,
+                  NULL));
+
+  // Create a FuzzTest struct to read into
+  FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL);
+  FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct);
+
+  // Try to read the struct from the fuzz data
+  THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error);
+  
+  // Clean up
+  g_object_unref(test_struct);
+  g_object_unref(protocol);
+  g_object_unref(transport);
+  g_object_unref(tconfiguration);
+  if (error) {
+    g_error_free(error);
+  }
+
+  return 0;
+} 
\ No newline at end of file
diff --git a/lib/c_glib/test/fuzz/fuzz_parse_compact.c b/lib/c_glib/test/fuzz/fuzz_parse_compact.c
new file mode 100644
index 0000000..5e0e2c1
--- /dev/null
+++ b/lib/c_glib/test/fuzz/fuzz_parse_compact.c
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thrift/c_glib/protocol/thrift_compact_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/transport/thrift_memory_buffer.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/thrift_configuration.h>
+#include <stdint.h>
+#include "gen-c_glib/fuzz_test_no_uuid_types.h"
+#include <stdio.h>
+
+// 10MB message size limit to prevent over-allocation during fuzzing
+#define FUZZ_MAX_MESSAGE_SIZE (10 * 1024 * 1024)
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  GError* error = NULL;
+  
+  // Create a GByteArray with the fuzz data
+  GByteArray* byte_array = g_byte_array_new();
+  g_byte_array_append(byte_array, data, size);
+
+  // Create a ThriftConfiguration with message size limits
+  ThriftConfiguration* tconfiguration = g_object_new(THRIFT_TYPE_CONFIGURATION, 
+                                                     "max_message_size", FUZZ_MAX_MESSAGE_SIZE,
+                                                     "max_frame_size", FUZZ_MAX_MESSAGE_SIZE, 
+                                                     NULL);
+
+  // Create a memory buffer transport with the byte array and configuration
+  ThriftTransport* transport = THRIFT_TRANSPORT(
+      g_object_new(THRIFT_TYPE_MEMORY_BUFFER,
+                  "buf", byte_array,
+                  "buf_size", size,
+                  "configuration", tconfiguration,
+                  NULL));
+
+  // Create a compact protocol
+  ThriftProtocol* protocol = THRIFT_PROTOCOL(
+      g_object_new(THRIFT_TYPE_COMPACT_PROTOCOL, 
+                  "transport", transport,
+                  NULL));
+
+  // // Create a FuzzTest struct to read into
+  FuzzTest* test_struct = g_object_new(TYPE_FUZZ_TEST, NULL);
+  FuzzTestClass* cls = FUZZ_TEST_GET_CLASS(test_struct);
+
+  // Try to read the struct from the fuzz data
+  THRIFT_STRUCT_CLASS(cls)->read(THRIFT_STRUCT(test_struct), protocol, &error);
+  
+  // Clean up
+  g_object_unref(test_struct);
+  g_object_unref(protocol);
+  g_object_unref(transport);
+  g_object_unref(tconfiguration);
+  if (error) {
+    g_error_free(error);
+  }
+
+  return 0;
+} 
\ No newline at end of file