Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gstreamer for openSUSE:Factory checked in at 2026-11-09 16:02:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gstreamer (Old) and /work/SRC/openSUSE:Factory/.gstreamer.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gstreamer" Mon Nov 9 16:02:55 2026 rev:128 rq:1395941 version:1.28.9 Changes: -------- --- /work/SRC/openSUSE:Factory/gstreamer/gstreamer.changes 2026-10-10 14:59:25.652099865 +0200 +++ /work/SRC/openSUSE:Factory/.gstreamer.new.3759290/gstreamer.changes 2026-11-09 16:03:02.910800547 +0100 @@ -1,0 +2,47 @@ +Fri Nov 6 18:48:43 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 1.28.9: + * Highlighted bugfixes: + + Various security fixes and playback fixes + + decodebin3, playbin3: fix assertion that would crash music players with + certain files and sources + + qtdemux: fix seeking beyond the end of file in push mode + + flvdemux: don't prematurely EOS on AVC/audio sequence end + + rtspsrc: Reuse non-compliant URL fallback across tracks + + H.264 and H.265 RTP depayloader header extension tracking fixes + + level: Add 24 bits support + + gtk4paintablesink: Mark EGL display as foreign to not terminate it + + amfcodec: fix rate_control (H.265, AV1) and gop_size (H.265) properties + + asio: fix stopping asio element causing crashes + + cuda: Correctly save alpha and blend on property change + + HLS: fix awss3hlssink EXT-X-PROGRAM-DATE-TIME moving at twice the speed + of the target duration + + hlssink3: Fix stream writing regression for CMAF and WebVTT sinks + + isobmff: Fix NTP seconds roll-over past 2036 + + Fix gap event regression in MPEG-PS demuxer with certain subtitle streams + + qsv, d3d11, d3d12: Build fixes on latest msys2 environment + + va: do not advertise unsupported formats in encoder caps + + v4l2 video decoder fixes including delay negotiation for H.264 and H.265 + for better decodebin2 compatibility + + wayland: output hotplug fixes + + webrtcsink: add support of mpph264enc encoder (rockchip) + + Rust plugins: enable cross-compilation with sysroot in Meson build + + cerbero: update ca-certificates and pip, and fix issue with rolling + distro versions + + Various bug fixes, build fixes, memory leak fixes, and other stability + and reliability improvements + * gstreamer: + + paramspecs: Fix GType name mess with GstParamSpecArray/Fraction + + taglist: don't critical when parsing random strings + + value: Skip the caps attempt when a bracketed value can't be caps + + value: unset the GValue when parsing a value token fails + + value: validate int/double/fraction ranges when parsing + + doc: Passing size=-1 to gst_buffer_extract_dup() returns all data + + baseparse: Don't dereference frame->buffer after a zero-sized + finish_frame() and explicitly forbid negative skip values from + handle_frame() + + base: Avoid memcpy()/memset() with NULL pointers and zero size + + ptp: Make sure the ptp-helper tests are compiled and running unless tests + are disabled + +------------------------------------------------------------------- Old: ---- gstreamer-1.28.8.tar.xz New: ---- gstreamer-1.28.9.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gstreamer.spec ++++++ --- /var/tmp/diff_new_pack.FzuyiK/_old 2026-11-09 16:03:03.795837646 +0100 +++ /var/tmp/diff_new_pack.FzuyiK/_new 2026-11-09 16:03:03.797837729 +0100 @@ -19,7 +19,7 @@ %define gst_branch 1.0 Name: gstreamer -Version: 1.28.8 +Version: 1.28.9 Release: 0 Summary: Streaming-Media Framework Runtime License: LGPL-2.1-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.FzuyiK/_old 2026-11-09 16:03:03.826838945 +0100 +++ /var/tmp/diff_new_pack.FzuyiK/_new 2026-11-09 16:03:03.830839113 +0100 @@ -5,7 +5,7 @@ <param name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param> <param name="subdir">subprojects/gstreamer</param> <param name="filename">gstreamer</param> - <param name="revision">1.28.8</param> + <param name="revision">1.28.9</param> <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param> <param name="versionrewrite-pattern">v?(.*)\+0</param> <param name="versionrewrite-replacement">\1</param> ++++++ gstreamer-1.28.8.tar.xz -> gstreamer-1.28.9.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/gst/gstbuffer.c new/gstreamer-1.28.9/gst/gstbuffer.c --- old/gstreamer-1.28.8/gst/gstbuffer.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/gst/gstbuffer.c 2026-11-06 13:54:37.000000000 +0100 @@ -2596,7 +2596,7 @@ * gst_buffer_extract_dup: * @buffer: a #GstBuffer * @offset: the offset to extract - * @size: the size to extract + * @size: the size to extract, G_MAXSIZE (-1) for all data after @offset * @dest: (array length=dest_size) (element-type guint8) (out): A pointer where * the destination array will be written. Might be %NULL if the size is 0. * @dest_size: (out): A location where the size of @dest can be written @@ -2621,7 +2621,7 @@ *dest_size = 0; } else { *dest = g_malloc (alloc_size); - *dest_size = gst_buffer_extract (buffer, offset, *dest, size); + *dest_size = gst_buffer_extract (buffer, offset, *dest, alloc_size); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/gst/gstparamspecs.c new/gstreamer-1.28.9/gst/gstparamspecs.c --- old/gstreamer-1.28.8/gst/gstparamspecs.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/gst/gstparamspecs.c 2026-11-06 13:54:37.000000000 +0100 @@ -139,7 +139,7 @@ _gst_param_fraction_values_cmp, /* values_cmp */ }; pspec_info.value_type = gst_fraction_get_type (); - type = g_param_type_register_static ("GstParamFraction", &pspec_info); + type = g_param_type_register_static ("GstParamSpecFraction", &pspec_info); g_once_init_leave (&gst_faction_type, type); } @@ -320,7 +320,7 @@ _gst_param_array_values_cmp, /* values_cmp */ }; pspec_info.value_type = gst_value_array_get_type (); - type = g_param_type_register_static ("GstParamArray", &pspec_info); + type = g_param_type_register_static ("GstParamSpecArray", &pspec_info); g_once_init_leave (&gst_array_type, type); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/gst/gsttaglist.c new/gstreamer-1.28.9/gst/gsttaglist.c --- old/gstreamer-1.28.8/gst/gsttaglist.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/gst/gsttaglist.c 2026-11-06 13:54:37.000000000 +0100 @@ -896,7 +896,10 @@ GstStructure *s; g_return_val_if_fail (str != NULL, NULL); - g_return_val_if_fail (g_str_has_prefix (str, "taglist"), NULL); + if (G_UNLIKELY (!g_str_has_prefix (str, "taglist"))) { + GST_WARNING ("invalid taglist string: '%s'", str); + return NULL; + } s = gst_structure_from_string (str, NULL); if (s == NULL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/gst/gstvalue.c new/gstreamer-1.28.9/gst/gstvalue.c --- old/gstreamer-1.28.8/gst/gstvalue.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/gst/gstvalue.c 2026-11-06 13:54:37.000000000 +0100 @@ -2706,6 +2706,7 @@ _priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value, GType type) { + const char *orig = s; GValue value1 = { 0 }; GValue value2 = { 0 }; GValue value3 = { 0 }; @@ -2762,17 +2763,30 @@ s++; if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2)) - return FALSE; + goto err; if (have_step && G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value3)) - return FALSE; + goto err; if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) { + if (gst_g_value_get_double_unchecked (&value1) >= + gst_g_value_get_double_unchecked (&value2)) + goto err; range_type = GST_TYPE_DOUBLE_RANGE; g_value_init (value, range_type); gst_value_set_double_range (value, gst_g_value_get_double_unchecked (&value1), gst_g_value_get_double_unchecked (&value2)); } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) { + if (gst_g_value_get_int_unchecked (&value1) >= + gst_g_value_get_int_unchecked (&value2)) + goto err; + if (have_step) { + gint step = gst_g_value_get_int_unchecked (&value3); + if (step <= 0 || + gst_g_value_get_int_unchecked (&value1) % step != 0 || + gst_g_value_get_int_unchecked (&value2) % step != 0) + goto err; + } range_type = GST_TYPE_INT_RANGE; g_value_init (value, range_type); if (have_step) @@ -2784,6 +2798,16 @@ gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1), gst_g_value_get_int_unchecked (&value2)); } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) { + if (gst_g_value_get_int64_unchecked (&value1) >= + gst_g_value_get_int64_unchecked (&value2)) + goto err; + if (have_step) { + gint64 step = gst_g_value_get_int64_unchecked (&value3); + if (step <= 0 || + gst_g_value_get_int64_unchecked (&value1) % step != 0 || + gst_g_value_get_int64_unchecked (&value2) % step != 0) + goto err; + } range_type = GST_TYPE_INT64_RANGE; g_value_init (value, range_type); if (have_step) @@ -2796,6 +2820,9 @@ gst_g_value_get_int64_unchecked (&value1), gst_g_value_get_int64_unchecked (&value2)); } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) { + if (gst_util_fraction_compare (value1.data[0].v_int, value1.data[1].v_int, + value2.data[0].v_int, value2.data[1].v_int) >= 0) + goto err; range_type = GST_TYPE_FRACTION_RANGE; g_value_init (value, range_type); gst_value_set_fraction_range (value, &value1, &value2); @@ -2807,6 +2834,7 @@ return TRUE; err: + GST_WARNING ("failed to parse range %s", orig); g_value_unset (value); g_value_unset (&value1); g_value_unset (&value2); @@ -2975,8 +3003,11 @@ memset (&list_value, 0, sizeof (list_value)); ret = _priv_gst_value_parse_value (s, &s, &list_value, type, element_spec); - if (!ret) + if (!ret) { + /* parse_value() zeroes the element on failure; a no-op safeguard. */ + g_value_unset (&list_value); return FALSE; + } _gst_value_list_append_val (vlist, &list_value); @@ -3064,17 +3095,52 @@ return ret; } +/* Whether a '[...]' value could parse as #GstCaps even though it did not + * parse as a #GstStructure. A caps list starts with the same name and fields + * as a plain structure, so the only way the caps parser accepts something the + * structure parser rejects at the first structure is a '(features)' clause + * directly after the name. Without one, both parsers run the identical name + * and fields parse and fail at the same place. + * + * The end of the name is located by scanning, not by parsing: the value + * parsers unescape quoted names in place (_priv_gst_value_parse_string ()) + * and this check must not modify the string. */ +static gboolean +_priv_gst_value_bracket_may_be_caps (const gchar * str) +{ + const gchar *s; + + if (*str != '[') + return TRUE; + + s = str + 1; + while (g_ascii_isspace (*s)) + s++; + + if (*s == '"') { + s++; + while (*s != '"') { + if (*s == '\\') + s++; + if (*s == '\0') + return TRUE; + s++; + } + s++; + } else { + while (*s && !g_ascii_isspace (*s) && !strchr ("\"(),;=", *s)) + s++; + } + + return *s == '('; +} + static gboolean _priv_gst_value_parse_range_struct_caps (gchar * s, gchar ** after, GValue * value, GType type) { - gint i; gchar *tmp = s; gboolean ret = FALSE; - GType try_types[] = { - GST_TYPE_STRUCTURE, - GST_TYPE_CAPS, - }; if (type == GST_TYPE_CAPS || type == GST_TYPE_STRUCTURE) ret = _priv_gst_value_parse_struct_or_caps (tmp, &tmp, type, value); @@ -3090,14 +3156,25 @@ if (type != G_TYPE_INVALID) return ret; - for (i = 0; i < G_N_ELEMENTS (try_types); i++) { - tmp = s; - ret = _priv_gst_value_parse_struct_or_caps (tmp, &tmp, try_types[i], value); - if (ret) - goto ok; - } + tmp = s; + ret = _priv_gst_value_parse_struct_or_caps (tmp, &tmp, GST_TYPE_STRUCTURE, + value); + if (ret) + goto ok; - return ret; + /* Caps differs from a plain structure only where a '(features)' clause can + * follow the first name; without one the caps attempt repeats the failed + * structure attempt. Trying both at every nesting level makes parsing of + * nested untyped values exponential in the nesting depth. */ + if (!_priv_gst_value_bracket_may_be_caps (s)) + return FALSE; + + tmp = s; + ret = _priv_gst_value_parse_struct_or_caps (tmp, &tmp, GST_TYPE_CAPS, value); + if (ret) + goto ok; + + return FALSE; ok: *after = tmp; @@ -3198,8 +3275,10 @@ } else { g_value_init (value, type); - if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, FALSE))) + if (G_UNLIKELY (!_priv_gst_value_parse_string (s, &value_end, &s, FALSE))) { + g_value_unset (value); return FALSE; + } /* Set NULL terminator for deserialization */ value_s = g_strndup (value_s, value_end - value_s); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/gstreamer.doap new/gstreamer-1.28.9/gstreamer.doap --- old/gstreamer-1.28.8/gstreamer.doap 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/gstreamer.doap 2026-11-06 13:54:37.000000000 +0100 @@ -40,6 +40,16 @@ <release> <Version> + <revision>1.28.9</revision> + <branch>1.28</branch> + <name></name> + <created>2026-11-06</created> + <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.28.9.tar.xz" /> + </Version> + </release> + + <release> + <Version> <revision>1.28.8</revision> <branch>1.28</branch> <name></name> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/base/gstbaseparse.c new/gstreamer-1.28.9/libs/gst/base/gstbaseparse.c --- old/gstreamer-1.28.8/libs/gst/base/gstbaseparse.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/base/gstbaseparse.c 2026-11-06 13:54:37.000000000 +0100 @@ -2333,6 +2333,8 @@ /* subclass can only do one of these, or semantics are too unclear */ g_assert (*skip == 0 || *flushed == 0); + /* negative skips are invalid and lead to infinite loops below */ + g_assert (*skip >= 0); /* track skipping */ if (*skip > 0) { @@ -2389,8 +2391,10 @@ } if (*skip == 0 && *flushed == 0) { - /* Carry over discont if we need more data */ - if (GST_BUFFER_IS_DISCONT (frame->buffer)) + /* Carry over discont if we need more data. A subclass may also have + * finished the frame without consuming input (size 0 with an out_buffer), + * in which case the buffer was already pushed and frame->buffer is NULL. */ + if (frame->buffer && GST_BUFFER_IS_DISCONT (frame->buffer)) parse->priv->discont = TRUE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/base/gstbaseparse.h new/gstreamer-1.28.9/libs/gst/base/gstbaseparse.h --- old/gstreamer-1.28.8/libs/gst/base/gstbaseparse.h 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/base/gstbaseparse.h 2026-11-06 13:54:37.000000000 +0100 @@ -244,7 +244,9 @@ /** * GstBaseParseClass::handle_frame: - * @skipsize: (out): + * @skipsize: (out): amount of bytes to skip from the start of the + * frame if no frame could be parsed, 0 if no skipping is needed. + * Negative values are invalid. * * Parses the input data into valid frames as defined by subclass * which should be passed to gst_base_parse_finish_frame(). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/base/gstbitwriter.h new/gstreamer-1.28.9/libs/gst/base/gstbitwriter.h --- old/gstreamer-1.28.8/libs/gst/base/gstbitwriter.h 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/base/gstbitwriter.h 2026-11-06 13:54:37.000000000 +0100 @@ -238,6 +238,9 @@ gst_bit_writer_put_bytes_unchecked (GstBitWriter * bitwriter, const guint8 * data, guint nbytes) { + if (G_UNLIKELY (nbytes == 0)) + return; + if ((bitwriter->bit_size & 0x07) == 0) { memcpy (&bitwriter->data[bitwriter->bit_size >> 3], data, nbytes); bitwriter->bit_size += (nbytes << 3); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/base/gstbytereader.h new/gstreamer-1.28.9/libs/gst/base/gstbytereader.h --- old/gstreamer-1.28.8/libs/gst/base/gstbytereader.h 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/base/gstbytereader.h 2026-11-06 13:54:37.000000000 +0100 @@ -361,10 +361,16 @@ static inline guint8 * gst_byte_reader_dup_data_unchecked (GstByteReader * reader, guint size) { - gconstpointer data = gst_byte_reader_get_data_unchecked (reader, size); - guint8 *dup_data = (guint8 *) g_malloc (size); + gconstpointer data; + guint8 *dup_data; + if (G_UNLIKELY (size == 0)) + return NULL; + + data = gst_byte_reader_get_data_unchecked (reader, size); + dup_data = (guint8 *) g_malloc (size); memcpy (dup_data, data, size); + return dup_data; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/base/gstbytewriter.h new/gstreamer-1.28.9/libs/gst/base/gstbytewriter.h --- old/gstreamer-1.28.8/libs/gst/base/gstbytewriter.h 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/base/gstbytewriter.h 2026-11-06 13:54:37.000000000 +0100 @@ -319,6 +319,9 @@ gst_byte_writer_put_data_unchecked (GstByteWriter * writer, const guint8 * data, guint size) { + if (G_UNLIKELY (size == 0)) + return; + memcpy ((guint8 *) & writer->parent.data[writer->parent.byte], data, size); writer->parent.byte += size; writer->parent.size = MAX (writer->parent.size, writer->parent.byte); @@ -341,6 +344,9 @@ static inline void gst_byte_writer_fill_unchecked (GstByteWriter * writer, guint8 value, guint size) { + if (G_UNLIKELY (size == 0)) + return; + memset ((guint8 *) & writer->parent.data[writer->parent.byte], value, size); writer->parent.byte += size; writer->parent.size = MAX (writer->parent.size, writer->parent.byte); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/helpers/ptp/io.rs new/gstreamer-1.28.9/libs/gst/helpers/ptp/io.rs --- old/gstreamer-1.28.8/libs/gst/helpers/ptp/io.rs 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/helpers/ptp/io.rs 2026-11-06 13:54:37.000000000 +0100 @@ -472,7 +472,7 @@ net::UdpSocket, os::windows::{io::AsRawSocket, raw::HANDLE}, ptr, - sync::{Arc, Condvar, Mutex, OnceLock}, + sync::{Arc, Condvar, Mutex}, thread, }; @@ -1310,18 +1310,24 @@ /// /// This does not implement any locking so usage from multiple threads at once will likely /// cause interleaved output. + #[cfg(not(test))] pub struct Stderr(HANDLE); + #[cfg(not(test))] struct SyncHandle(HANDLE); // SAFETY: This is a single-threaded application and even otherwise writing from // multiple threads at once to a pipe is safe and will only cause interleaved output. + #[cfg(not(test))] unsafe impl Send for SyncHandle {} + #[cfg(not(test))] unsafe impl Sync for SyncHandle {} /// Lazily-initialized stderr handle. Set once, either by `init_named_pipe` (before any /// logging) or on first `acquire()` call via the inherited standard error handle. - static STDERR_HANDLE: OnceLock<SyncHandle> = OnceLock::new(); + #[cfg(not(test))] + static STDERR_HANDLE: std::sync::OnceLock<SyncHandle> = std::sync::OnceLock::new(); + #[cfg(not(test))] impl Stderr { /// Open a named pipe for writing and use it as the stderr handle. /// @@ -1355,7 +1361,6 @@ Ok(()) } - #[cfg(not(test))] pub fn acquire() -> Self { let sync_handle = STDERR_HANDLE.get_or_init(|| { // SAFETY: GetStdHandle returns a borrowed handle, or 0 if none is set or -1 if an @@ -1394,6 +1399,7 @@ } } + #[cfg(not(test))] impl Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { <&Stderr as Write>::write(&mut &*self, buf) @@ -1404,6 +1410,7 @@ } } + #[cfg(not(test))] impl Write for &Stderr { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { if self.0 == INVALID_HANDLE_VALUE { @@ -1438,7 +1445,7 @@ } // `Stderr` is not used when tests are enabled as no logging is performed to stderr. -#[cfg_attr(test, allow(unused_imports))] +#[cfg(not(test))] pub use self::imp::Stderr; pub use self::imp::{Poll, Stdin, Stdout}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/helpers/ptp/main.rs new/gstreamer-1.28.9/libs/gst/helpers/ptp/main.rs --- old/gstreamer-1.28.8/libs/gst/helpers/ptp/main.rs 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/helpers/ptp/main.rs 2026-11-06 13:54:37.000000000 +0100 @@ -120,6 +120,7 @@ let args = args::parse_args().context("Failed parsing commandline parameters")?; #[cfg(windows)] + #[cfg(not(test))] if let Some(ref pipe_err) = args.pipe_err { io::Stderr::init_named_pipe(pipe_err).context("Failed initializing stderr named pipe")?; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/libs/gst/helpers/ptp/meson.build new/gstreamer-1.28.9/libs/gst/helpers/ptp/meson.build --- old/gstreamer-1.28.8/libs/gst/helpers/ptp/meson.build 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/libs/gst/helpers/ptp/meson.build 2026-11-06 13:54:37.000000000 +0100 @@ -117,7 +117,7 @@ install : true) # sanity checking -if get_option('tests').enabled() +if get_option('tests').allowed() exe_test = executable('gst_ptp_helper_test', 'main.rs', override_options : ['rust_std=2018'], rust_args : ['--test', rust_args], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/meson.build new/gstreamer-1.28.9/meson.build --- old/gstreamer-1.28.8/meson.build 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/meson.build 2026-11-06 13:54:37.000000000 +0100 @@ -1,5 +1,5 @@ project('gstreamer', 'c', - version : '1.28.8', + version : '1.28.9', meson_version : '>= 1.4', default_options : [ 'warning_level=1', 'buildtype=debugoptimized', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/scripts/dist-common-files.py new/gstreamer-1.28.9/scripts/dist-common-files.py --- old/gstreamer-1.28.8/scripts/dist-common-files.py 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/scripts/dist-common-files.py 2026-11-06 13:54:37.000000000 +0100 @@ -46,7 +46,10 @@ source_root, '..', '..', 'release-notes', major_minor, f'release-notes-{major_minor}.md') with open(relnotes_src, 'r') as f: lines = f.readlines() - if not f'### {project_version}\n' in lines: + if not f' - version: "{project_version}"\n' in lines: + sys.exit( + f'Update {relnotes_src} first, must contain a header entry for {project_version}') + if not f'### {project_version} {{#{project_version}}}\n' in lines: sys.exit( f'Update {relnotes_src} first, must contain a section for {project_version}') if not project_version.endswith('.0'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.8/tests/check/gst/gstvalue.c new/gstreamer-1.28.9/tests/check/gst/gstvalue.c --- old/gstreamer-1.28.8/tests/check/gst/gstvalue.c 2026-10-08 17:20:32.000000000 +0200 +++ new/gstreamer-1.28.9/tests/check/gst/gstvalue.c 2026-11-06 13:54:37.000000000 +0100 @@ -331,6 +331,55 @@ GST_END_TEST; +GST_START_TEST (test_deserialize_unterminated_string_failures) +{ + GValue value = G_VALUE_INIT; + const char *strings[] = { + "\"unterminated", /* quoted string without closing quote */ + "\"unterminated\\", /* trailing escape eats the terminator */ + "{ \"unterminated }", /* unterminated string as a list element */ + }; + int i; + + /* On failure the destination keeps the type it was initialized to and + * holds no value, so a storage-allocating type must have released what + * its init allocated. */ + g_value_init (&value, GST_TYPE_LIST); + + for (i = 0; i < G_N_ELEMENTS (strings); ++i) { + fail_if (gst_value_deserialize (&value, strings[i]), + "deserialized %s (%d), while it should have failed", strings[i], i); + fail_unless_equals_int (G_VALUE_TYPE (&value), GST_TYPE_LIST); + fail_unless (G_VALUE_HOLDS (&value, GST_TYPE_LIST)); + fail_unless_equals_int (gst_value_list_get_size (&value), 0); + } + + g_value_unset (&value); +} + +GST_END_TEST; + +GST_START_TEST (test_deserialize_list_element_failures) +{ + const char *strings[] = { + "f/x,f={(list)", /* element cast to a list at end of input */ + "f/x,f={ (string) \"unterminated }", /* unterminated string element */ + "f/x,f={ (int) 1, \"unterminated }", /* bad element after a good one */ + }; + int i; + + /* Structure fields are parsed into a not-yet-initialized GValue: on + * failure it must be left unset again, with no element storage leaked + * by the failed element parse. */ + for (i = 0; i < G_N_ELEMENTS (strings); ++i) { + GstStructure *s = gst_structure_from_string (strings[i], NULL); + fail_if (s != NULL, "parsed %s (%d), while it should have failed", + strings[i], i); + } +} + +GST_END_TEST; + GST_START_TEST (test_deserialize_guint) { GValue value = { 0 }; @@ -3858,19 +3907,16 @@ str = g_strdup_printf ("foo/bar, range=[ 1, %" G_GINT64_FORMAT " ];", (gint64) G_MAXINT + 1); - s = NULL; - ASSERT_CRITICAL (s = gst_structure_from_string (str, &end)); + s = gst_structure_from_string (str, &end); + fail_unless (s == NULL); g_free (str); - if (s) - gst_structure_free (s); str = g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT " ];", (gint64) G_MAXINT, (gint64) G_MAXINT + 1); - ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL)); + s = gst_structure_from_string (str, NULL); + fail_unless (s == NULL); end = NULL; g_free (str); - if (s) - gst_structure_free (s); /* check a valid int64_range deserialization. Those ranges need to * be explicit about their storage type. */ @@ -3892,23 +3938,18 @@ str = g_strdup_printf ("foo/bar, range=(gint64)[ 1, %" G_GUINT64_FORMAT " ];", (guint64) G_MAXINT64 + 1); - s = NULL; - ASSERT_CRITICAL (s = gst_structure_from_string (str, &end)); - if (s) { - fail_unless (*end == '\0'); - gst_structure_free (s); - end = NULL; - } + s = gst_structure_from_string (str, &end); + fail_unless (s == NULL); + end = NULL; g_free (str); /* check invalid int64_range deserialization into a int64_range */ str = g_strdup_printf ("foo/bar, range=(gint64)[ %" G_GINT64_FORMAT ", %" G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1); - ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL)); + s = gst_structure_from_string (str, NULL); + fail_unless (s == NULL); g_free (str); - if (s) - gst_structure_free (s); /* check invalid int64_range deserialization into a int_range */ str = @@ -3986,9 +4027,8 @@ /* check we cannot parse bad ranges */ for (n = 0; n < G_N_ELEMENTS (bad_ranges); ++n) { str = g_strdup_printf ("foo/bar, range=%s", bad_ranges[n]); - ASSERT_CRITICAL (s = gst_structure_from_string (str, &end)); - if (s) - gst_structure_free (s); + s = gst_structure_from_string (str, &end); + fail_unless (s == NULL); g_free (str); } } @@ -4930,6 +4970,30 @@ GST_END_TEST; +GST_START_TEST (test_deserialize_deeply_nested_brackets) +{ + /* Trying both a structure and a caps parse for every nested untyped + * bracketed value made parsing of a failing value exponential in the + * nesting depth: at depth 28 this takes several minutes without the + * skip in _priv_gst_value_parse_range_struct_caps (). */ + GValue value = G_VALUE_INIT; + GString *str = g_string_new (NULL); + guint i; + + for (i = 0; i < 28; i++) + g_string_append (str, "{[s, f= "); + g_string_append (str, "$"); + for (i = 0; i < 28; i++) + g_string_append (str, "]}"); + + g_value_init (&value, GST_TYPE_LIST); + fail_if (gst_value_deserialize (&value, str->str)); + g_value_unset (&value); + g_string_free (str, TRUE); +} + +GST_END_TEST; + GST_START_TEST (test_serialize_deserialize_sample) { GstSample *samp, *samp2; @@ -5484,6 +5548,8 @@ tcase_add_test (tc_chain, test_serialize_buffer); tcase_add_test (tc_chain, test_deserialize_gint); tcase_add_test (tc_chain, test_deserialize_gint_failures); + tcase_add_test (tc_chain, test_deserialize_unterminated_string_failures); + tcase_add_test (tc_chain, test_deserialize_list_element_failures); tcase_add_test (tc_chain, test_deserialize_guint); tcase_add_test (tc_chain, test_deserialize_guint_failures); tcase_add_test (tc_chain, test_deserialize_gint64); @@ -5545,6 +5611,7 @@ tcase_add_test (tc_chain, test_transform_list_to_string); tcase_add_test (tc_chain, test_deserialize_with_pspec); tcase_add_test (tc_chain, test_deserialize_serialize_nested_structures); + tcase_add_test (tc_chain, test_deserialize_deeply_nested_brackets); tcase_add_test (tc_chain, test_serialize_deserialize_segment); tcase_add_test (tc_chain, test_serialize_deserialize_caps_features); tcase_add_test (tc_chain, test_serialize_deserialize_tag_list); ++++++ gstreamer.obsinfo ++++++ --- /var/tmp/diff_new_pack.FzuyiK/_old 2026-11-09 16:03:04.208854958 +0100 +++ /var/tmp/diff_new_pack.FzuyiK/_new 2026-11-09 16:03:04.211855084 +0100 @@ -1,5 +1,5 @@ name: gstreamer -version: 1.28.8 -mtime: 1791472832 -commit: 1b2a95a1b72787cda146b46df9605b168e5b683b +version: 1.28.9 +mtime: 1793969677 +commit: 3ced45da096032bdac8e0922faa492a079c3180e
