diff --git a/server/gstreamer-encoder.c b/server/gstreamer-encoder.c index 7a75923d4626b1a2c18e01500c0be9f979f1fe1b..21ba6f27d50353c44b62a7c2d87fedcc6967628f 100644 --- a/server/gstreamer-encoder.c +++ b/server/gstreamer-encoder.c @@ -20,6 +20,7 @@ #include <inttypes.h> #include <pthread.h> +#include <ctype.h> // ignore static constants variable not used #if defined(__GNUC__) && (__GNUC__ >= 6) @@ -861,16 +862,29 @@ static const gchar* get_gst_codec_name(const SpiceGstEncoder *encoder) } } -static gchar *get_gst_converter(void) +static gpointer gst_pref_format_once(gpointer arg) { - gchar *converter, *pref_format; + const gchar *pref_format; pref_format = getenv("SPICE_CONVERTER_PREFERRED_FORMAT"); - if (pref_format) { - converter = g_strconcat("videoconvert ! video/x-raw,format=", pref_format, NULL); - } else { - converter = g_strdup("videoconvert"); + // for security limit the format to 64 characters and only alphanumeric or underscores + if (pref_format && pref_format[0] && strlen(pref_format) <= 64) { + const gchar *p; + for (p = pref_format; *p; ++p) { + if (!isalnum(*p) && *p != '_') { + goto wrong_format; + } + } + return g_strconcat("videoconvert ! video/x-raw,format=", pref_format, NULL); } - return converter; + +wrong_format: + return (gpointer) "videoconvert"; +} + +static gchar *get_gst_converter(void) +{ + static GOnce gst_once = G_ONCE_INIT; + return g_strdup((const gchar*) g_once(&gst_once, gst_pref_format_once, NULL)); } static gboolean create_pipeline(SpiceGstEncoder *encoder)