pidgin/pidgin

Fix incompatible type conversion errors
release-2.x.y
3 months ago, Elliott Sales de Andrade
488055ab5531
Fix incompatible type conversion errors

- A recent libxml2 changed its handler function to take a `const` pointer. It's
safe for us to have it, and them not, but the opposite way causes an implicit
cast warning.
- In relatively new GLib (many years now), `g_object_ref` casts its output to
match its input. This means we should not be casting to `G_OBJECT`, as that
is not the type it expects, and would translate to the output being `GObject`
instead of the original type.

This fixes the build in Fedora 40, which changes several incompatible pointer
conversion warnings into errors.

This patch is partially from the Fedora maintainer @yarda, with some corrections by me (to the `g_object_ref` portions.)

Testing Done:
Compiled in a Rawhide environment with this patch applied.

Bugs closed: PIDGIN-17850

Reviewed at https://reviews.imfreedom.org/r/2944/
# Introduction and setup
Pidgin has fuzzing support for libpurple via
[Libfuzzer](https://llvm.org/docs/LibFuzzer.html). If you're new to fuzzing with
libfuzzer, there is a fantastic tutorial available
[here](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md).
The fuzzers reside in libpurples/fuzzers. To build them, you'll need to specify
`clang` as your C compiler as well as pass `--enable-fuzzing` to `./configure`.
Once this is done you can `cd libpurple/fuzzers` and run `make check` to build
the fuzzers.
Example:
```bash
$ CC=clang ./configure --enable-fuzzing --disable-cyrus-sasl --disable-gtkui --disable-gstreamer --disable-vv --disable-idn --disable-meanwhile --disable-avahi --disable-libgadu --disable-dbus --disable-libsecret --disable-gnome-keyring --disable-kwallet --disable-plugins
```
Now that the build system has been configured, you need to build everything,
including the fuzzers. You can do this with the following command. Note that the
`-j $(nproc)` tells make to build with all available cores and is recommended
but optional.
```bash
$ make -j $(nproc) check
```
Now that the fuzzers are built, you can run them directly. There is also an
optional `-dict` parameter that can be used to specify a dictionary to be used
during the process. Also all fuzzers must have a basic corpus to help the
fuzzer find values and should be located in the fuzzers/corpus/<fuzzer-name>
directory.
```bash
$ ./fuzz_xmlnode -dict=dictionaries/xml.dict corpus/xmlnode
```
# Useful options
Because Libfuzzer is a sophisticated program, here are some handy options that
are available in all fuzzers.
* **-help=1** Print help.
* **-jobs=1** Number of jobs to run. If jobs >= 1 this will spawn that many jobs in separate worker processes with stdout/stderr redirected to fuzz-JOB.log.
* **-workers=0** Number of simultaneous worker processes to run the jobs. If zero, `min(jobs,NumberOfCpuCores()/2)` is used.
* **-max_len=0** Maximum length of the test input. If 0, libFuzzer tries to guess a good value based on the corpus and reports it.
# Adding more fuzzers
Of course, having more fuzzers and covering more areas of the code base is
always a good thing. It's simple to incorporate a fuzzer into the current build
system! If you open the `Makefile.am` file in `libpurple/fuzzers` you'll see a
`check_PROGRAMS` variable, you have to add the name to your new fuzzing harness
in there.
Example:
```
fuzz_programs=\
fuzz_html_to_xhtml \
fuzz_jabber_caps \
fuzz_jabber_id_new \
fuzz_markup_strip_html \
fuzz_mime \
fuzz_xmlnode \
fuzz_newfuzzer # This is the newly added fuzzer
```
You'll also need to define the sources, which we can do by copying and changing
the lines from an existing fuzzer.
For example we have a `fuzz_xmlnode.c` fuzzer, these are the lines that define
the sources and the flags:
```
fuzz_xmlnode_SOURCES=fuzz_xmlnode.c
fuzz_xmlnode_LDADD=$(check_libpurple_LDADD)
fuzz_xmlnode_CFLAGS=-fsanitize=fuzzer,address $(check_libpurple_CFLAGS)
```
You'll need to change the names of these to match the name of our new fuzzer and
add any necessary flags:
```
fuzz_new_SOURCES=fuzz_new.c
fuzz_new_LDADD=$(common_LDADD)
fuzz_new_CFLAGS=-fsanitize=fuzzer,address $(common_CFLAGS)
```
Now you must include your harness in `fuzz_new.c`, an example of a new harness
could be as follows:
```C
#include <glib.h>
#include <string.h>
#include <purple.h>
gint LLVMFuzzerTestOneInput(const guint8 *data, size_t size);
gint
LLVMFuzzerTestOneInput(const guint8 *data, size_t size) {
gchar *malicious_input = g_new0(gchar, size + 1);
memcpy(malicious_input, data, size);
malicious_input[size] = '\0';
function_you_want_to_fuzz(malicious_input);
g_free(malicious_input);
return 0;
}
```
Make sure to include the relevant headers and then run `make check`. This will
force an update of the build system and build everything that needs to be
rebuilt. If there were no issues, you should now be able to run your new fuzzer
from the `libpurple/fuzzers` directory.