gstreamer/ci/fuzzing/gst-discoverer.c
Matthew Waters bd5d24822a build/fuzzing: integrate fuzz targets into the build system
Currently disabled but may be enabled later.

Updates the existing fuzzing to use shared libraries as that's easier
for meson to deal with if there is a mix of static and shared libraries
on the system.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2123>
2022-04-07 08:17:35 +10:00

116 lines
3.1 KiB
C

/*
* Copyright 2016 Google Inc.
* author: Edward Hervey <bilboed@bilboed.com>
*
* Licensed 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.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <locale.h>
#include <stdlib.h>
#include <glib.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
/* push-based discoverer fuzzing target
*
* This application can be compiled with libFuzzer to simulate
* a push-based discoverer execution.
*
* To reproduce the failing behaviour, use:
* $ gst-discoverer-1.0 pushfile:///...
*
* The goal is to cover basic usage of demuxers, parsers and
* base decoder elements.
*
* When compiling, only link the required demuxer/parser/decoder
* plugins and keep it to a limited range (ex: ogg/theora/vorbis)
*
**/
const guint8 *fuzztesting_data;
size_t fuzztesting_size;
static void
appsrc_configuration (GstDiscoverer * dc, GstElement * source, gpointer data)
{
GstBuffer *buf;
GstFlowReturn ret;
/* Create buffer from fuzztesting_data which shouldn't be freed */
buf =
gst_buffer_new_wrapped_full (0, (gpointer) fuzztesting_data,
fuzztesting_size, 0, fuzztesting_size, NULL, NULL);
g_object_set (G_OBJECT (source), "size", fuzztesting_size, NULL);
g_signal_emit_by_name (G_OBJECT (source), "push-buffer", buf, &ret);
gst_buffer_unref (buf);
}
static void
custom_logger (const gchar * log_domain,
GLogLevelFlags log_level, const gchar * message, gpointer unused_data)
{
if (log_level & G_LOG_LEVEL_CRITICAL) {
g_printerr ("CRITICAL ERROR : %s\n", message);
abort ();
} else if (log_level & G_LOG_LEVEL_WARNING) {
g_printerr ("WARNING : %s\n", message);
}
}
int
LLVMFuzzerTestOneInput (const guint8 * data, size_t size)
{
GError *err = NULL;
GstDiscoverer *dc;
gint timeout = 10;
GstDiscovererInfo *info;
static gboolean initialized = FALSE;
if (!initialized) {
/* We want critical warnings to assert so we can fix them */
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
g_log_set_default_handler (custom_logger, NULL);
/* Only initialize and register plugins once */
gst_init (NULL, NULL);
initialized = TRUE;
}
dc = gst_discoverer_new (timeout * GST_SECOND, &err);
if (G_UNLIKELY (dc == NULL)) {
g_print ("Error initializing: %s\n", err->message);
g_clear_error (&err);
exit (1);
}
fuzztesting_data = data;
fuzztesting_size = size;
/* Connect to source-setup signal to give the data */
g_signal_connect (dc, "source-setup", (GCallback) appsrc_configuration, NULL);
info = gst_discoverer_discover_uri (dc, "appsrc://", &err);
g_clear_error (&err);
if (info)
gst_discoverer_info_unref (info);
g_object_unref (dc);
return 0;
}