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
 

Reply via email to