Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gstreamer-plugins-base for
openSUSE:Factory checked in at 2026-07-12 16:20:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-base (Old)
and /work/SRC/openSUSE:Factory/.gstreamer-plugins-base.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gstreamer-plugins-base"
Sun Jul 12 16:20:41 2026 rev:132 rq:1364876 version:1.28.5
Changes:
--------
---
/work/SRC/openSUSE:Factory/gstreamer-plugins-base/gstreamer-plugins-base.changes
2026-06-13 18:47:16.029254136 +0200
+++
/work/SRC/openSUSE:Factory/.gstreamer-plugins-base.new.1991/gstreamer-plugins-base.changes
2026-07-12 16:21:12.408104434 +0200
@@ -1,0 +2,31 @@
+Thu Jul 9 17:18:19 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 1.28.5:
+ + appsink: Clear local sample storage when flushing
+ + appsrc: Uniformly handle EOS events being pushed
+ + audio-resampler-neon fails to build for targets with neon but
+ without thumb
+ + encoding-target: Validate that encoding profile name is UTF-8
+ before using it
+ + gldownload: fix wrong DRM format negotiation causing R/B
+ channel swap
+ + opusdec: Don't use any channel positions for >64 channels
+ + rtcpbuffer: Fix parsing of SR+SDES compound packets (regression
+ from security fix)
+ + subparse: Don't allow very small framerates for microdvd
+ subtitles
+ + typefind: assorted fixes for the image-rs plugin typefinding
+ + typefindhelper: Drop unnecessary check for factories without a
+ function
+ + WBMP typefinding rejects a valid 1280x800 file
+ + typefinding: detect animation on PNG (and WebP, GIF, AVIF)
+ + typefindfunctions: remove Sun and Andrew raster format
+ typefinders
+ + uridecodebin3: deactivate input_item in erroneous ready->paused
+ transition
+ + vorbistag: Check for enough base64 data before trying to decode
+ + xmptag: Don't allocate -1 bytes of memory if there's only a
+ single tag
+ + xmptag: Handle fractions with 0 denominator as invalid
+
+-------------------------------------------------------------------
Old:
----
gst-plugins-base-1.28.4.obscpio
New:
----
gst-plugins-base-1.28.5.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ gstreamer-plugins-base.spec ++++++
--- /var/tmp/diff_new_pack.oGsJru/_old 2026-07-12 16:21:13.508142060 +0200
+++ /var/tmp/diff_new_pack.oGsJru/_new 2026-07-12 16:21:13.508142060 +0200
@@ -20,7 +20,7 @@
%define gst_branch 1.0
%define gstreamer_req_version %(echo %{version} | sed -e "s/+.*//")
Name: gstreamer-plugins-base
-Version: 1.28.4
+Version: 1.28.5
Release: 0
Summary: GStreamer Streaming-Media Framework Plug-Ins
License: GPL-2.0-or-later AND LGPL-2.1-or-later
++++++ _service ++++++
--- /var/tmp/diff_new_pack.oGsJru/_old 2026-07-12 16:21:13.544143291 +0200
+++ /var/tmp/diff_new_pack.oGsJru/_new 2026-07-12 16:21:13.560143838 +0200
@@ -5,7 +5,7 @@
<param
name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param>
<param name="subdir">subprojects/gst-plugins-base</param>
<param name="filename">gst-plugins-base</param>
- <param name="revision">1.28.4</param>
+ <param name="revision">1.28.5</param>
<param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
<param name="versionrewrite-pattern">v?(.*)\+0</param>
<param name="versionrewrite-replacement">\1</param>
++++++ gst-plugins-base-1.28.4.obscpio -> gst-plugins-base-1.28.5.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/ext/gl/gstgldownloadelement.c
new/gst-plugins-base-1.28.5/ext/gl/gstgldownloadelement.c
--- old/gst-plugins-base-1.28.4/ext/gl/gstgldownloadelement.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/ext/gl/gstgldownloadelement.c 2026-07-08
23:42:39.000000000 +0200
@@ -976,7 +976,7 @@
if (!context) {
gst_structure_remove_field (s, "drm-format");
} else if (gst_gl_dma_buf_transform_gst_formats_to_drm_formats (context,
- fmtval, GST_GL_DRM_FORMAT_DIRECT_IMPORT, &drmfmtval)) {
+ fmtval, GST_GL_DRM_FORMAT_INCLUDE_EMULATED, &drmfmtval)) {
gst_structure_set_value (s, "drm-format", &drmfmtval);
g_value_unset (&drmfmtval);
} else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/ext/opus/gstopusdec.c
new/gst-plugins-base-1.28.5/ext/opus/gstopusdec.c
--- old/gst-plugins-base-1.28.4/ext/opus/gstopusdec.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/ext/opus/gstopusdec.c 2026-07-08
23:42:39.000000000 +0200
@@ -364,6 +364,8 @@
GST_DEBUG_OBJECT (dec, "Using a default of 2 channels");
dec->n_channels = 2;
pos = NULL;
+ } else if (dec->n_channels > 64) {
+ pos = NULL;
}
if (dec->sample_rate == 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst/playback/gsturidecodebin3.c
new/gst-plugins-base-1.28.5/gst/playback/gsturidecodebin3.c
--- old/gst-plugins-base-1.28.4/gst/playback/gsturidecodebin3.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst/playback/gsturidecodebin3.c 2026-07-08
23:42:39.000000000 +0200
@@ -2092,8 +2092,12 @@
/* ERRORS */
failure:
{
- if (transition == GST_STATE_CHANGE_READY_TO_PAUSED)
+ if (transition == GST_STATE_CHANGE_READY_TO_PAUSED) {
purge_play_items (uridecodebin);
+ if (uridecodebin->input_item) {
+ uridecodebin->input_item->active = FALSE;
+ }
+ }
return ret;
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/gst/subparse/gstsubparse.c
new/gst-plugins-base-1.28.5/gst/subparse/gstsubparse.c
--- old/gst-plugins-base-1.28.4/gst/subparse/gstsubparse.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst/subparse/gstsubparse.c 2026-07-08
23:42:39.000000000 +0200
@@ -538,7 +538,7 @@
rest = g_strdup (line);
g_strdelimit (rest, ",", '.');
fps = g_ascii_strtod (rest, &end);
- if (end != rest && fps > 0.0 && fps <= 240.0) {
+ if (end != rest && fps >= 0.001 && fps <= 1000.0) {
gst_util_double_to_fraction (fps, &state->fps_n, &state->fps_d);
GST_INFO ("framerate from file: %d/%d ('%s')", state->fps_n,
state->fps_d, rest);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctions.c
new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctions.c
--- old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctions.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctions.c
2026-07-08 23:42:39.000000000 +0200
@@ -3738,7 +3738,7 @@
done:
if (tip > 0) {
if (variant) {
- GstCaps *caps = gst_caps_copy (QT_CAPS);
+ GstCaps *caps = gst_caps_make_writable (QT_CAPS);
gst_caps_set_simple (caps, "variant", G_TYPE_STRING, variant, NULL);
gst_type_find_suggest (tf, tip, caps);
@@ -4231,7 +4231,7 @@
num_markers = 1;
data_scan_ctx_advance (tf, &c, 2);
- caps = gst_caps_copy (JPEG_CAPS);
+ caps = gst_caps_make_writable (JPEG_CAPS);
while (data_scan_ctx_ensure_data (tf, &c, 4) && c.offset < (200 * 1024)) {
guint16 len;
@@ -6100,6 +6100,69 @@
gst_type_find_suggest (tf, GST_TYPE_FIND_MINIMUM, PXSTR_CAPS);
}
+/* image/png (animated=true) */
+
+static GstStaticCaps png_caps = GST_STATIC_CAPS ("image/png");
+#define PNG_CAPS (gst_static_caps_get(&png_caps))
+
+/* how many chunks we check before we give up */
+#define PNG_MAXCHUNKS 25
+
+static void
+png_type_find (GstTypeFind * tf, gpointer unused)
+{
+ DataScanCtx c = { 0, NULL, 0 };
+ gboolean animated = FALSE;
+ GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
+ guint chunks = 0;
+ static const guint8 signature[] =
+ { 0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a };
+
+ if (!data_scan_ctx_ensure_data (tf, &c, 8))
+ return;
+
+ if (memcmp (c.data, signature, sizeof (signature)) != 0)
+ return;
+
+ /* At least we found the right magic */
+ prob = GST_TYPE_FIND_LIKELY;
+ data_scan_ctx_advance (tf, &c, 8);
+
+ while (data_scan_ctx_ensure_data (tf, &c, 8)) {
+ // length: uint32_be
+ // type: fourcc
+ // <data>
+ // <crc32>: uint8[4]
+ const guint32 length = GST_READ_UINT32_BE (&c.data[0]);
+ const guint32 chunk = GST_READ_UINT32_LE (&c.data[4]);
+ // Test for critical chunks and the acTL chunk
+ if (chunk == GST_MAKE_FOURCC ('a', 'c', 'T', 'L')) {
+ animated = TRUE;
+ prob = GST_TYPE_FIND_NEARLY_CERTAIN;
+ } else if (chunk == GST_MAKE_FOURCC ('P', 'L', 'T', 'E')) {
+ prob = GST_TYPE_FIND_NEARLY_CERTAIN;
+ } else if (chunk == GST_MAKE_FOURCC ('I', 'D', 'A', 'T')) {
+ prob = GST_TYPE_FIND_MAXIMUM;
+ break;
+ }
+
+ data_scan_ctx_advance (tf, &c, 4 + 4);
+ data_scan_ctx_advance (tf, &c, length);
+ data_scan_ctx_advance (tf, &c, 4);
+ chunks++;
+
+ if (chunks >= PNG_MAXCHUNKS)
+ break;
+ }
+
+ if (animated) {
+ gst_type_find_suggest_simple (tf, prob, "image/png", "animated",
+ G_TYPE_BOOLEAN, TRUE, NULL);
+ } else {
+ gst_type_find_suggest (tf, prob, PNG_CAPS);
+ }
+}
+
/*** application/x-smk ***/
static GstStaticCaps smk_caps = GST_STATIC_CAPS ("application/x-smk");
@@ -6485,7 +6548,7 @@
if (data == NULL)
return;
- /* want 0x00 0x00 at start */
+ /* want WBMP type 0 + empty FixHeaderField */
if (*data++ != 0 || *data++ != 0)
return;
@@ -6495,8 +6558,10 @@
/* let's assume max width/height is 65536 */
w = *data++;
if ((w & 0x80)) {
- w = (w << 8) | *data++;
- if ((w & 0x80))
+ /* It's a multibyte integer, mask continuation bit and add */
+ w = ((w & 0x7F) << 7) | (*data & 0x7F);
+ /* Block > 65536px images */
+ if ((*data & 0x80))
return;
++size;
data = gst_type_find_peek (find, 4, 2);
@@ -6505,8 +6570,8 @@
}
h = *data++;
if ((h & 0x80)) {
- h = (h << 8) | *data++;
- if ((h & 0x80))
+ h = ((h & 0x7F) << 7) | (*data & 0x7F);
+ if ((*data & 0x80))
return;
++size;
}
@@ -7058,6 +7123,8 @@
tiff_type_find, "tif,tiff", TIFF_CAPS, NULL, NULL);
GST_TYPE_FIND_REGISTER_DEFINE (exr, "image/x-exr", GST_RANK_PRIMARY,
exr_type_find, "exr", EXR_CAPS, NULL, NULL);
+GST_TYPE_FIND_REGISTER_DEFINE (png, "image/png", GST_RANK_PRIMARY + 14,
+ png_type_find, "png", PNG_CAPS, NULL, NULL);
GST_TYPE_FIND_REGISTER_DEFINE (pnm, "image/x-portable-pixmap",
GST_RANK_SECONDARY, pnm_type_find, "pnm,ppm,pgm,pbm", PNM_CAPS, NULL,
NULL);
GST_TYPE_FIND_REGISTER_DEFINE (matroska, "video/x-matroska", GST_RANK_PRIMARY,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctionsplugin.h
new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctionsplugin.h
--- old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctionsplugin.h
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctionsplugin.h
2026-07-08 23:42:39.000000000 +0200
@@ -69,6 +69,7 @@
GST_TYPE_FIND_REGISTER_DECLARE (xcf);
GST_TYPE_FIND_REGISTER_DECLARE (mng);
GST_TYPE_FIND_REGISTER_DECLARE (jng);
+GST_TYPE_FIND_REGISTER_DECLARE (xbm);
GST_TYPE_FIND_REGISTER_DECLARE (xpm);
GST_TYPE_FIND_REGISTER_DECLARE (ras);
GST_TYPE_FIND_REGISTER_DECLARE (bz2);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctionsstartwith.c
new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctionsstartwith.c
--- old/gst-plugins-base-1.28.4/gst/typefind/gsttypefindfunctionsstartwith.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst/typefind/gsttypefindfunctionsstartwith.c
2026-07-08 23:42:39.000000000 +0200
@@ -102,9 +102,6 @@
GST_RANK_PRIMARY, "rf64", "RF64", 4, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER_START_WITH_DEFINE (gif, "image/gif", GST_RANK_PRIMARY,
"gif", "GIF8", 4, GST_TYPE_FIND_MAXIMUM);
-TYPE_FIND_REGISTER_START_WITH_DEFINE (png, "image/png",
- GST_RANK_PRIMARY + 14, "png", "\211PNG\015\012\032\012", 8,
- GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER_START_WITH_DEFINE (mve, "video/x-mve",
GST_RANK_SECONDARY, "mve",
"Interplay MVE File\032\000\032\000\000\001\063\021", 26,
@@ -123,6 +120,8 @@
TYPE_FIND_REGISTER_START_WITH_DEFINE (jng, "image/x-jng",
GST_RANK_SECONDARY, "jng", "\213JNG\015\012\032\012", 8,
GST_TYPE_FIND_MAXIMUM);
+TYPE_FIND_REGISTER_START_WITH_DEFINE (xbm, "image/x-xbitmap",
+ GST_RANK_SECONDARY, "xbm", "/* XBM */", 9, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER_START_WITH_DEFINE (xpm, "image/x-xpixmap",
GST_RANK_SECONDARY, "xpm", "/* XPM */", 9, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER_START_WITH_DEFINE (ras, "image/x-sun-raster",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst-libs/gst/app/gstappsink.c
new/gst-plugins-base-1.28.5/gst-libs/gst/app/gstappsink.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/app/gstappsink.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/app/gstappsink.c 2026-07-08
23:42:39.000000000 +0200
@@ -991,6 +991,18 @@
}
static void
+gst_app_sink_clear_sample_contents (GstAppSink * appsink)
+{
+ GstAppSinkPrivate *priv = appsink->priv;
+
+ priv->sample = gst_sample_make_writable (priv->sample);
+ gst_sample_set_buffer (priv->sample, NULL);
+ gst_sample_set_buffer_list (priv->sample, NULL);
+ gst_sample_set_caps (priv->sample, NULL);
+ gst_sample_set_segment (priv->sample, NULL);
+}
+
+static void
gst_app_sink_flush_unlocked (GstAppSink * appsink)
{
GstMiniObject *obj;
@@ -1004,6 +1016,7 @@
gst_queue_status_info_reset (&priv->queue_status_info);
+ gst_app_sink_clear_sample_contents (appsink);
gst_caps_replace (&priv->last_caps, NULL);
g_cond_signal (&priv->cond);
priv->in = priv->out = priv->dropped = 0;
@@ -1022,11 +1035,7 @@
priv->started = TRUE;
gst_segment_init (&priv->preroll_segment, GST_FORMAT_TIME);
gst_segment_init (&priv->last_segment, GST_FORMAT_TIME);
- priv->sample = gst_sample_make_writable (priv->sample);
- gst_sample_set_buffer (priv->sample, NULL);
- gst_sample_set_buffer_list (priv->sample, NULL);
- gst_sample_set_caps (priv->sample, NULL);
- gst_sample_set_segment (priv->sample, NULL);
+ gst_app_sink_clear_sample_contents (appsink);
priv->in = priv->out = priv->dropped = 0;
g_mutex_unlock (&priv->mutex);
@@ -1050,11 +1059,7 @@
gst_caps_replace (&priv->last_caps, NULL);
gst_segment_init (&priv->preroll_segment, GST_FORMAT_UNDEFINED);
gst_segment_init (&priv->last_segment, GST_FORMAT_UNDEFINED);
- priv->sample = gst_sample_make_writable (priv->sample);
- gst_sample_set_buffer (priv->sample, NULL);
- gst_sample_set_buffer_list (priv->sample, NULL);
- gst_sample_set_caps (priv->sample, NULL);
- gst_sample_set_segment (priv->sample, NULL);
+ gst_app_sink_clear_sample_contents (appsink);
priv->in = priv->out = priv->dropped = 0;
g_mutex_unlock (&priv->mutex);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/gst-libs/gst/app/gstappsrc.c
new/gst-plugins-base-1.28.5/gst-libs/gst/app/gstappsrc.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/app/gstappsrc.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/app/gstappsrc.c 2026-07-08
23:42:39.000000000 +0200
@@ -1132,6 +1132,9 @@
g_object_notify (G_OBJECT (appsrc), "dropped");
}
break;
+ case GST_EVENT_EOS:
+ gst_app_src_end_of_stream (appsrc);
+ break;
default:
if (GST_EVENT_IS_SERIALIZED (event)) {
GST_DEBUG_OBJECT (appsrc, "queue event: %" GST_PTR_FORMAT, event);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst-libs/gst/pbutils/descriptions.c
new/gst-plugins-base-1.28.5/gst-libs/gst/pbutils/descriptions.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/pbutils/descriptions.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/pbutils/descriptions.c
2026-07-08 23:42:39.000000000 +0200
@@ -258,7 +258,6 @@
{"image/ppm", "Portable PixMap (PPM)", FLAG_IMAGE, "ppm"},
{"image/svg+xml", "Scalable Vector Graphics (SVG)", FLAG_IMAGE, "svg"},
{"image/tiff", "TIFF", FLAG_IMAGE, "tiff"},
- {"image/x-cmu-raster", "CMU Raster Format", FLAG_IMAGE, ""},
{"image/x-degas", "DEGAS", FLAG_IMAGE, ""},
{"image/x-icon", "ICO", FLAG_IMAGE, "ico"},
{"image/x-j2c", "JPEG 2000", FLAG_VIDEO | FLAG_IMAGE, ""},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst-libs/gst/pbutils/encoding-target.c
new/gst-plugins-base-1.28.5/gst-libs/gst/pbutils/encoding-target.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/pbutils/encoding-target.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/pbutils/encoding-target.c
2026-07-08 23:42:39.000000000 +0200
@@ -919,12 +919,15 @@
GError ** error)
{
gint i;
- gchar *p, *lname, *lfilename = NULL, *tldir, **encoding_target_dirs;
+ gchar *p, *lname = NULL, *lfilename = NULL, *tldir, **encoding_target_dirs;
const gchar *envvar;
GstEncodingTarget *target = NULL;
g_return_val_if_fail (name != NULL, NULL);
+ if (!g_utf8_validate (name, -1, NULL))
+ goto invalid_name;
+
p = lname = g_str_to_ascii (name, NULL);
for (; *p; ++p)
*p = g_ascii_tolower (*p);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst-libs/gst/rtp/gstrtcpbuffer.c
new/gst-plugins-base-1.28.5/gst-libs/gst/rtp/gstrtcpbuffer.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/rtp/gstrtcpbuffer.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/rtp/gstrtcpbuffer.c
2026-07-08 23:42:39.000000000 +0200
@@ -1272,29 +1272,20 @@
return TRUE;
}
-/**
- * gst_rtcp_packet_sdes_next_item:
- * @packet: a valid SDES #GstRTCPPacket
- *
- * Move to the next SDES item in @packet.
- *
- * Returns: TRUE if there was a next item.
- */
-gboolean
-gst_rtcp_packet_sdes_next_item (GstRTCPPacket * packet)
+static guint
+find_sdes_next_item_offset (GstRTCPPacket * packet)
{
guint8 *data;
guint offset;
guint len;
- g_return_val_if_fail (packet != NULL, FALSE);
- g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
- g_return_val_if_fail (packet->rtcp != NULL, FALSE);
- g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);
+ g_return_val_if_fail (packet != NULL, 0);
+ g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
+ g_return_val_if_fail (packet->rtcp != NULL, 0);
/* if we are at the last item, we are done */
if (packet->item_count == packet->count)
- return FALSE;
+ return 0;
/* move to SDES */
data = packet->rtcp->map.data;
@@ -1304,7 +1295,7 @@
/* skip SSRC */
offset += 4;
- /* don't overrun - use total packet size */
+ /* use total packet size */
len = (packet->length + 1) << 2;
while (offset < len) {
@@ -1314,10 +1305,39 @@
break;
}
if (offset + 1 >= len)
- return FALSE;
+ return 0;
offset += data[offset + 1] + 2;
}
+ return offset;
+}
+
+/**
+ * gst_rtcp_packet_sdes_next_item:
+ * @packet: a valid SDES #GstRTCPPacket
+ *
+ * Move to the next SDES item in @packet.
+ *
+ * Returns: TRUE if there was a next item.
+ */
+gboolean
+gst_rtcp_packet_sdes_next_item (GstRTCPPacket * packet)
+{
+ guint offset;
+ guint len;
+
+ g_return_val_if_fail (packet != NULL, FALSE);
+ g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
+ g_return_val_if_fail (packet->rtcp != NULL, FALSE);
+ g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);
+
+ offset = find_sdes_next_item_offset (packet);
+ if (offset == 0)
+ return FALSE;
+
+ /* use total packet size */
+ len = (packet->length + 1) << 2;
+
/* needs at least SSRC and one item plus padding */
if (offset + 4 + 4 > len)
return FALSE;
@@ -1350,18 +1370,16 @@
/* move to SDES */
data = packet->rtcp->map.data;
- guint offset = packet->offset;
- /* move to item */
- offset += packet->item_offset;
+ data += packet->offset;
/* don't overrun - use total packet size */
guint len = (packet->length + 1) << 2;
/* needs at least SSRC and one item plus padding */
- if (offset + 4 + 4 > len)
+ if (packet->item_offset + 4 + 4 > len)
return 0;
- ssrc = GST_READ_UINT32_BE (data + offset);
+ ssrc = GST_READ_UINT32_BE (data + packet->item_offset);
return ssrc;
}
@@ -1585,15 +1603,28 @@
g_return_val_if_fail (packet->rtcp != NULL, FALSE);
g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
+ maxsize = packet->rtcp->map.maxsize;
+
/* increment item count when possible */
if (packet->count >= GST_RTCP_MAX_SDES_ITEM_COUNT)
goto no_space;
- /* pretend there is a next packet for the next call */
- packet->count++;
+ /* Find the next free slot. The first item always goes at
+ * item_offset=4 (set by read_packet_header). For subsequent items
+ * we must skip past the current item and bail out if the SDES is
+ * too small to hold another one. Otherwise the next add_item()
+ * would silently overwrite the previous one at the previous
+ * item_offset. */
+ if (packet->count > 0) {
+ offset = find_sdes_next_item_offset (packet);
+ if (offset == 0 || packet->offset + offset + 8 > maxsize)
+ goto no_space;
+ packet->item_offset = offset;
+ packet->item_count++;
+ packet->entry_offset = 4;
+ }
- /* jump over current item */
- gst_rtcp_packet_sdes_next_item (packet);
+ packet->count++;
/* move to SDES */
data = packet->rtcp->map.data;
@@ -1602,8 +1633,11 @@
/* move to current item */
offset = packet->item_offset;
- /* we need 2 free words now */
- if (offset + 8 >= maxsize)
+ /* we need 2 free words. packet->offset may be non-zero for a SDES
+ * that follows another packet in a compound buffer, so compare
+ * against the absolute write position. Using the relative offset
+ * would allow appending past the buffer's maxsize. */
+ if (packet->offset + offset + 8 >= maxsize)
goto no_next;
/* write SSRC */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/gst-libs/gst/tag/gstvorbistag.c
new/gst-plugins-base-1.28.5/gst-libs/gst/tag/gstvorbistag.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/tag/gstvorbistag.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/tag/gstvorbistag.c 2026-07-08
23:42:39.000000000 +0200
@@ -318,7 +318,7 @@
static void
gst_vorbis_tag_add_coverart (GstTagList * tags, gchar * img_data_base64,
- gint base64_len)
+ gsize base64_len)
{
GstSample *img;
gsize img_len;
@@ -369,7 +369,7 @@
*/
static void
gst_vorbis_tag_add_metadata_block_picture (GstTagList * tags,
- gchar * value, gint value_len)
+ gchar * value, gsize value_len)
{
GstByteReader reader;
guint32 img_len = 0, img_type = 0;
@@ -377,6 +377,9 @@
gsize decoded_len;
const guint8 *data = NULL;
+ if (value_len < 2)
+ goto not_enough_data;
+
/* img_data_base64 points to a temporary copy of the base64 encoded data, so
* it's safe to do inpace decoding here
*/
@@ -414,13 +417,25 @@
return;
+/* ERRORS */
+not_enough_data:
+ {
+ GST_WARNING
+ ("METADATA_BLOCK_PICTURE tag with too little base64-encoded data");
+ return;
+ }
error:
- GST_WARNING
- ("Couldn't extract image or image type from METADATA_BLOCK_PICTURE tag");
- return;
+ {
+ GST_WARNING
+ ("Couldn't extract image or image type from METADATA_BLOCK_PICTURE
tag");
+ return;
+ }
decode_failed:
- GST_WARNING ("Failed to decode Base64 data from METADATA_BLOCK_PICTURE tag");
- return;
+ {
+ GST_WARNING
+ ("Failed to decode Base64 data from METADATA_BLOCK_PICTURE tag");
+ return;
+ }
}
/**
@@ -455,7 +470,7 @@
gchar *cur, *value;
guint cur_size;
guint iterations;
- guint value_len;
+ gsize value_len;
GstTagList *list;
g_return_val_if_fail (data != NULL, NULL);
@@ -490,7 +505,8 @@
*value = '\0';
value++;
value_len = strlen (value);
- if (value_len == 0 || !g_utf8_validate (value, value_len, NULL)) {
+ if (value_len == 0 || value_len > G_MAXSSIZE
+ || !g_utf8_validate (value, value_len, NULL)) {
g_free (cur);
continue;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/gst-libs/gst/tag/gstxmptag.c
new/gst-plugins-base-1.28.5/gst-libs/gst/tag/gstxmptag.c
--- old/gst-plugins-base-1.28.4/gst-libs/gst/tag/gstxmptag.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-libs/gst/tag/gstxmptag.c 2026-07-08
23:42:39.000000000 +0200
@@ -631,7 +631,7 @@
return;
}
- if (sscanf (altitude_str, "%d/%d", &frac_n, &frac_d) != 2) {
+ if (sscanf (altitude_str, "%d/%d", &frac_n, &frac_d) != 2 || frac_d == 0) {
GST_WARNING ("Failed to parse fraction: %s", altitude_str);
return;
}
@@ -724,7 +724,7 @@
return;
}
- if (sscanf (speed_str, "%d/%d", &frac_n, &frac_d) != 2) {
+ if (sscanf (speed_str, "%d/%d", &frac_n, &frac_d) != 2 || frac_d == 0) {
GST_WARNING ("Failed to parse fraction: %s", speed_str);
return;
}
@@ -819,7 +819,7 @@
return;
}
- if (sscanf (dir_str, "%d/%d", &frac_n, &frac_d) != 2) {
+ if (sscanf (dir_str, "%d/%d", &frac_n, &frac_d) != 2 || frac_d == 0) {
GST_WARNING ("Failed to parse fraction: %s", dir_str);
return;
}
@@ -1136,7 +1136,7 @@
gdouble value = 0;
gint frac_n, frac_d;
- if (sscanf (v, "%d/%d", &frac_n, &frac_d) == 2) {
+ if (sscanf (v, "%d/%d", &frac_n, &frac_d) == 2 && frac_d != 0) {
gst_util_fraction_to_double (frac_n, frac_d, &value);
gst_tag_list_add (list, merge_mode, tag, value, NULL);
} else {
@@ -1252,6 +1252,9 @@
while (*xp1 != '<' && xp1 < xpe)
xp1++;
+ if (xp2 < xp1)
+ goto missing_footer;
+
/* no tag can be longer than the whole buffer */
part = g_malloc (xp2 - xp1);
list = gst_tag_list_new_empty ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/gst-plugins-base.doap
new/gst-plugins-base-1.28.5/gst-plugins-base.doap
--- old/gst-plugins-base-1.28.4/gst-plugins-base.doap 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/gst-plugins-base.doap 2026-07-08
23:42:39.000000000 +0200
@@ -36,6 +36,16 @@
<release>
<Version>
+ <revision>1.28.5</revision>
+ <branch>1.28</branch>
+ <name></name>
+ <created>2026-07-08</created>
+ <file-release
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.28.5.tar.xz"
/>
+ </Version>
+ </release>
+
+ <release>
+ <Version>
<revision>1.28.4</revision>
<branch>1.28</branch>
<name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/meson.build
new/gst-plugins-base-1.28.5/meson.build
--- old/gst-plugins-base-1.28.4/meson.build 2026-06-12 14:19:43.000000000
+0200
+++ new/gst-plugins-base-1.28.5/meson.build 2026-07-08 23:42:39.000000000
+0200
@@ -1,5 +1,5 @@
project('gst-plugins-base', 'c',
- version : '1.28.4',
+ version : '1.28.5',
meson_version : '>= 1.4',
default_options : [ 'warning_level=1',
'buildtype=debugoptimized',
@@ -457,9 +457,10 @@
#include <arm_neon.h>
int32x4_t testfunc(int16_t *a, int16_t *b) {
asm volatile ("vmull.s16 q0, d0, d0" : : : "q0");
+ asm volatile ("add.w r1, r0, r0" : : : "r0", "r1");
return vmull_s16(vld1_s16(a), vld1_s16(b));
}
-''', name : 'NEON support')
+''', name : 'NEON with 32-bit wide Thumb support')
core_conf.set('HAVE_ARM_NEON', true)
endif
endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-base-1.28.4/tests/check/gst/typefindfunctions.c
new/gst-plugins-base-1.28.5/tests/check/gst/typefindfunctions.c
--- old/gst-plugins-base-1.28.4/tests/check/gst/typefindfunctions.c
2026-06-12 14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/tests/check/gst/typefindfunctions.c
2026-07-08 23:42:39.000000000 +0200
@@ -535,6 +535,108 @@
GST_END_TEST;
+GST_START_TEST (test_typefind_with_wav_dts_caps)
+{
+ GstTypeFindProbability prob;
+ const gchar *type;
+ GstBuffer *buf;
+ GstCaps *caps;
+ GstCaps *query_caps;
+ GList *factories;
+ guint8 *p;
+
+ /* WAV header (44 bytes) followed by two DTS frames (96 bytes each).
+ *
+ * The DTS typefinder scans within DTS_MAX_FRAMESIZE bytes and will
+ * find the DTS sync words after the WAV header. The WAV typefinder
+ * matches the RIFF/WAVE signature at offset 0.
+ *
+ * This tests the _with_caps scenario like in gstwavparse.c: where
+ * given a WAV stream, check if the content is actually DTS.
+ */
+ guint8 wav_dts_data[44 + 96 + 96];
+
+ p = wav_dts_data;
+
+ /* WAV header */
+ memcpy (p, "RIFF", 4);
+ GST_WRITE_UINT32_LE (p + 4, sizeof (wav_dts_data) - 8); /* file size -
8 */
+ memcpy (p + 8, "WAVE", 4);
+ memcpy (p + 12, "fmt ", 4);
+ GST_WRITE_UINT32_LE (p + 16, 16); /* chunk size */
+ GST_WRITE_UINT16_LE (p + 20, 1); /* PCM */
+ GST_WRITE_UINT16_LE (p + 22, 1); /* mono */
+ GST_WRITE_UINT32_LE (p + 24, 44100); /* sample rate */
+ GST_WRITE_UINT32_LE (p + 28, 88200); /* byte rate */
+ GST_WRITE_UINT16_LE (p + 32, 2); /* block align */
+ GST_WRITE_UINT16_LE (p + 34, 16); /* bits per sample */
+ memcpy (p + 36, "data", 4);
+ GST_WRITE_UINT32_LE (p + 40, 96 * 2); /* data size */
+
+ /* Two DTS frames at offset 44 (inside the WAV data chunk) */
+ GST_WRITE_UINT32_BE (p + 44, 0x7FFE8001); /* sync */
+ GST_WRITE_UINT16_BE (p + 48, 0x0014); /* num_blocks=5, frame_size high=0 */
+ GST_WRITE_UINT16_BE (p + 50, 0x05F0); /* frame_size low: (95<<4)=0x5F0 */
+ GST_WRITE_UINT16_BE (p + 52, 0x340F); /* sample_rate=48kHz */
+ GST_WRITE_UINT16_BE (p + 54, 0x2400); /* channels=6, lfe=0 */
+ memset (p + 56, 0, 96 - 12);
+
+ /* Second DTS frame at offset 140 */
+ GST_WRITE_UINT32_BE (p + 140, 0x7FFE8001);
+ GST_WRITE_UINT16_BE (p + 144, 0x0014);
+ GST_WRITE_UINT16_BE (p + 146, 0x05F0);
+ GST_WRITE_UINT16_BE (p + 148, 0x340F);
+ GST_WRITE_UINT16_BE (p + 150, 0x2400);
+ memset (p + 152, 0, 96 - 12);
+
+ buf = gst_buffer_new ();
+ gst_buffer_append_memory (buf,
+ gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+ wav_dts_data, sizeof (wav_dts_data), 0, sizeof (wav_dts_data),
+ NULL, NULL));
+ GST_BUFFER_OFFSET (buf) = 0;
+
+ /* list_factories_for_caps with audio/x-wav should return factories */
+ query_caps = gst_caps_from_string ("audio/x-wav");
+ factories = gst_type_find_list_factories_for_caps (NULL, query_caps);
+ fail_unless (factories != NULL);
+ g_list_free_full (factories, (GDestroyNotify) gst_object_unref);
+
+ /* typefind with audio/x-wav should find WAV */
+ prob = 0;
+ caps = gst_type_find_helper_for_buffer_with_caps (NULL, buf,
+ query_caps, &prob);
+ fail_unless (caps != NULL,
+ "WAV+DTS: typefind with audio/x-wav caps should find WAV");
+ type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
+ fail_unless_equals_string (type, "audio/x-wav");
+ fail_unless (prob == GST_TYPE_FIND_MAXIMUM);
+ gst_caps_unref (caps);
+ gst_caps_unref (query_caps);
+
+ /* list_factories_for_caps with audio/x-dts should return factories */
+ query_caps = gst_caps_from_string ("audio/x-dts");
+ factories = gst_type_find_list_factories_for_caps (NULL, query_caps);
+ fail_unless (factories != NULL);
+ g_list_free_full (factories, (GDestroyNotify) gst_object_unref);
+
+ /* typefind with audio/x-dts should find DTS (inside WAV data chunk) */
+ prob = 0;
+ caps = gst_type_find_helper_for_buffer_with_caps (NULL, buf,
+ query_caps, &prob);
+ fail_unless (caps != NULL,
+ "WAV+DTS: typefind with audio/x-dts caps should find DTS");
+ type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
+ fail_unless_equals_string (type, "audio/x-dts");
+ fail_unless (prob == GST_TYPE_FIND_MAXIMUM);
+ gst_caps_unref (caps);
+ gst_caps_unref (query_caps);
+
+ gst_buffer_unref (buf);
+}
+
+GST_END_TEST;
+
static Suite *
typefindfunctions_suite (void)
{
@@ -554,6 +656,7 @@
tcase_add_test (tc_chain, test_manifest_typefinding);
tcase_add_test (tc_chain, test_webvtt);
tcase_add_test (tc_chain, test_subparse);
+ tcase_add_test (tc_chain, test_typefind_with_wav_dts_caps);
return s;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/tests/check/libs/pbutils.c
new/gst-plugins-base-1.28.5/tests/check/libs/pbutils.c
--- old/gst-plugins-base-1.28.4/tests/check/libs/pbutils.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/tests/check/libs/pbutils.c 2026-07-08
23:42:39.000000000 +0200
@@ -335,8 +335,8 @@
"video/x-zlib", "image/bmp", "image/x-bmp",
"image/x-MS-bmp", "image/gif", "image/jpeg", "image/jng", "image/png",
"image/pbm", "image/ppm", "image/svg+xml", "image/tiff",
- "image/x-cmu-raster", "image/x-icon", "image/x-xcf", "image/x-pixmap",
- "image/x-xpixmap", "image/x-quicktime", "image/x-sun-raster",
+ "image/x-icon", "image/x-xcf", "image/x-pixmap",
+ "image/x-xpixmap", "image/x-quicktime",
"image/x-tga", "video/x-dv", "video/x-dv",
/* some RTP formats */
"application/x-rtp, media=(string)video, encoding-name=(string)TimVCodec",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-base-1.28.4/tests/check/libs/rtp.c
new/gst-plugins-base-1.28.5/tests/check/libs/rtp.c
--- old/gst-plugins-base-1.28.4/tests/check/libs/rtp.c 2026-06-12
14:19:43.000000000 +0200
+++ new/gst-plugins-base-1.28.5/tests/check/libs/rtp.c 2026-07-08
23:42:39.000000000 +0200
@@ -2671,6 +2671,247 @@
GST_END_TEST;
+GST_START_TEST (test_sdes_parsing_valid_in_compound_packet)
+{
+ /* Valid SDES packet as the second packet of an SR+SDES compound packet
+ * (RFC 3550 6.1). Its non-zero offset must not affect SDES parsing. */
+ GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+ GstRTCPPacket packet;
+ GstBuffer *buffer;
+ guint8 compound_data[] = {
+ 0x80, 0xc8, 0x00, 0x06, /* V=2, P=0, RC=0, PT=SR, length=6 (28 bytes)
*/
+ 0x12, 0x34, 0x56, 0x78, /* SSRC */
+ 0xed, 0xf2, 0xa1, 0x36, /* NTP timestamp, most significant word */
+ 0x70, 0x42, 0x90, 0x00, /* NTP timestamp, least significant word */
+ 0xcf, 0x35, 0x27, 0x2e, /* RTP timestamp */
+ 0x00, 0x00, 0x14, 0xd9, /* sender's packet count */
+ 0x00, 0x53, 0x72, 0x27, /* sender's octet count */
+ 0x81, 0xca, 0x00, 0x05, /* V=2, P=0, SC=1, PT=SDES, length=5 (24
bytes) */
+ 0x12, 0x34, 0x56, 0x78, /* SSRC */
+ 0x01, 0x0a, /* CNAME, length=10 */
+ 't', 'e', 's', 't', '@', 'f', 'o', 'o', '.', 'b',
+ 0x00, /* End of SDES item list */
+ 0x00, 0x00, 0x00 /* Pad chunk to 32-bit boundary (not RTCP
P-bit padding) */
+ };
+
+ buffer = gst_buffer_new_and_alloc (sizeof (compound_data));
+ gst_buffer_fill (buffer, 0, compound_data, sizeof (compound_data));
+
+ fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp));
+ fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
GST_RTCP_TYPE_SR);
+
+ /* move to the SDES packet */
+ fail_unless (gst_rtcp_packet_move_to_next (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
+ GST_RTCP_TYPE_SDES);
+
+ /* Get SSRC */
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x12345678);
+
+ /* Iterate items */
+ fail_unless (gst_rtcp_packet_sdes_first_item (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x12345678);
+
+ /* Iterate entries */
+ fail_unless (gst_rtcp_packet_sdes_first_entry (&packet));
+ {
+ guint8 *data;
+ guint8 len;
+ GstRTCPSDESType type;
+
+ fail_unless (gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data));
+ fail_unless_equals_int (type, GST_RTCP_SDES_CNAME);
+ fail_unless_equals_int (len, 10);
+ fail_unless (memcmp (data, "[email protected]", 10) == 0);
+ }
+ /* END marker is not an entry */
+ fail_if (gst_rtcp_packet_sdes_next_entry (&packet));
+ fail_if (gst_rtcp_packet_sdes_next_item (&packet));
+
+ gst_rtcp_buffer_unmap (&rtcp);
+ gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_sdes_add_item_bounds_check_in_compound_packet)
+{
+ /* Compound SR+SDES where SDES starts at non-zero offset (28) and its
+ * length field (4) claims room for another item at relative offset
+ * 12. Adding that item would write at absolute 28 + 12 + 8 = 48,
+ * i.e. exactly maxsize, so the bounds check must use the absolute
+ * position; using the relative item_offset would silently let the
+ * item be appended past maxsize.
+ *
+ * gst_buffer_new_and_alloc() rounds maxsize up for alignment,
+ * which would mask the bug; gst_buffer_new_wrapped_full() lets us
+ * pin maxsize to exactly the requested size. */
+ GstBuffer *buffer;
+ GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+ GstRTCPPacket packet;
+ guint8 *raw_data;
+ const gsize buf_size = 48;
+ guint8 compound_data[] = {
+ /* SR: 7 words = 28 bytes */
+ 0x80, 0xc8, 0x00, 0x06, /* V=2, P=0, RC=0, PT=SR, length=6 */
+ 0xaa, 0xaa, 0xaa, 0xaa, /* SSRC */
+ 0x00, 0x00, 0x00, 0x00, /* NTP timestamp, most significant word */
+ 0x00, 0x00, 0x00, 0x00, /* NTP timestamp, least significant word */
+ 0x00, 0x00, 0x00, 0x00, /* RTP timestamp */
+ 0x00, 0x00, 0x00, 0x00, /* sender's packet count */
+ 0x00, 0x00, 0x00, 0x00, /* sender's octet count */
+
+ /* SDES: 5 words = 20 bytes, SC=1, length=4 */
+ 0x81, 0xca, 0x00, 0x04, /* V=2, P=0, SC=1, PT=SDES, length=4 */
+ 0x12, 0x34, 0x56, 0x78, /* SSRC */
+ 0x00, 0x00, 0x00, 0x00, /* 0 entry (end-of-items) */
+ 0x00, 0x00, 0x00, 0x00, /* unused */
+ 0x00, 0x00, 0x00, 0x00, /* unused */
+ };
+
+ raw_data = g_malloc (buf_size);
+ memcpy (raw_data, compound_data, sizeof (compound_data));
+ buffer = gst_buffer_new_wrapped_full (0, raw_data, buf_size, 0, buf_size,
+ raw_data, g_free);
+
+ fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
+
+ fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
GST_RTCP_TYPE_SR);
+ fail_unless (gst_rtcp_packet_move_to_next (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
+ GST_RTCP_TYPE_SDES);
+ fail_unless_equals_int (gst_rtcp_packet_get_count (&packet), 1);
+ fail_unless_equals_int (gst_rtcp_packet_get_length (&packet), 4);
+ fail_unless_equals_int (rtcp.map.maxsize, buf_size);
+
+ /* Adding the item would push the SDES to absolute position 48,
+ * i.e. the end of the buffer. Must be rejected, and the packet
+ * must remain parseable afterwards. */
+ fail_if (gst_rtcp_packet_sdes_add_item (&packet, 0x87654321));
+ fail_unless (gst_rtcp_buffer_validate (buffer));
+
+ gst_rtcp_buffer_unmap (&rtcp);
+ fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp));
+
+ fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
GST_RTCP_TYPE_SR);
+ fail_unless (gst_rtcp_packet_move_to_next (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
+ GST_RTCP_TYPE_SDES);
+ fail_unless_equals_int (gst_rtcp_packet_get_count (&packet), 1);
+ fail_unless_equals_int (gst_rtcp_packet_get_length (&packet), 4);
+
+ fail_unless (gst_rtcp_packet_sdes_first_item (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x12345678);
+ fail_if (gst_rtcp_packet_sdes_first_entry (&packet));
+
+ gst_rtcp_buffer_unmap (&rtcp);
+ gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_sdes_add_item_and_parse)
+{
+ /* Positive test: add multiple SDES items and verify they can be parsed
back. */
+ GstBuffer *buffer;
+ GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+ GstRTCPPacket packet;
+
+ buffer = gst_rtcp_buffer_new (1400);
+ fail_unless (buffer != NULL);
+
+ fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
+
+ /* Add an SR packet first so validation passes */
+ fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SR, &packet));
+ gst_rtcp_packet_sr_set_sender_info (&packet, 0x12345678,
+ G_GUINT64_CONSTANT (0), 0, 0, 0);
+
+ /* Add an SDES packet */
+ fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SDES,
&packet));
+
+ /* Add multiple items with entries */
+ fail_unless (gst_rtcp_packet_sdes_add_item (&packet, 0x11111111));
+ fail_unless (gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_CNAME,
+ sizeof ("sender1") - 1, (guint8 *) "sender1"));
+
+ fail_unless (gst_rtcp_packet_sdes_add_item (&packet, 0x22222222));
+ fail_unless (gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_CNAME,
+ sizeof ("sender2") - 1, (guint8 *) "sender2"));
+
+ fail_unless (gst_rtcp_packet_sdes_add_item (&packet, 0x33333333));
+ fail_unless (gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_CNAME,
+ sizeof ("sender3") - 1, (guint8 *) "sender3"));
+
+ gst_rtcp_buffer_unmap (&rtcp);
+ /* Truncate buffer to actual size for validation to check the packets */
+ gst_buffer_set_size (buffer, rtcp.map.size);
+ fail_unless (gst_rtcp_buffer_validate (buffer));
+
+ /* Now parse the packet and verify all items are present */
+ fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp));
+
+ fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
GST_RTCP_TYPE_SR);
+ fail_unless (gst_rtcp_packet_move_to_next (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_get_type (&packet),
+ GST_RTCP_TYPE_SDES);
+ fail_unless_equals_int (gst_rtcp_packet_get_count (&packet), 3);
+
+ /* Verify first item */
+ fail_unless (gst_rtcp_packet_sdes_first_item (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x11111111);
+ fail_unless (gst_rtcp_packet_sdes_first_entry (&packet));
+ {
+ guint8 *data;
+ guint8 len;
+ GstRTCPSDESType type;
+ fail_unless (gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data));
+ fail_unless_equals_int (type, GST_RTCP_SDES_CNAME);
+ fail_unless_equals_int (len, 7);
+ fail_unless (memcmp (data, "sender1", 7) == 0);
+ }
+
+ /* Verify second item */
+ fail_unless (gst_rtcp_packet_sdes_next_item (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x22222222);
+ fail_unless (gst_rtcp_packet_sdes_first_entry (&packet));
+ {
+ guint8 *data;
+ guint8 len;
+ GstRTCPSDESType type;
+ fail_unless (gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data));
+ fail_unless_equals_int (type, GST_RTCP_SDES_CNAME);
+ fail_unless_equals_int (len, 7);
+ fail_unless (memcmp (data, "sender2", 7) == 0);
+ }
+
+ /* Verify third item */
+ fail_unless (gst_rtcp_packet_sdes_next_item (&packet));
+ fail_unless_equals_int (gst_rtcp_packet_sdes_get_ssrc (&packet), 0x33333333);
+ fail_unless (gst_rtcp_packet_sdes_first_entry (&packet));
+ {
+ guint8 *data;
+ guint8 len;
+ GstRTCPSDESType type;
+ fail_unless (gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data));
+ fail_unless_equals_int (type, GST_RTCP_SDES_CNAME);
+ fail_unless_equals_int (len, 7);
+ fail_unless (memcmp (data, "sender3", 7) == 0);
+ }
+
+ /* No more items */
+ fail_if (gst_rtcp_packet_sdes_next_item (&packet));
+
+ gst_rtcp_buffer_unmap (&rtcp);
+ gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
GST_START_TEST (test_sdes_parsing_truncated_entry)
{
/* SDES item with only SSRC and no entry data at all */
@@ -2889,6 +3130,9 @@
tcase_add_test (tc_chain, test_sdes_parsing_out_of_bounds);
tcase_add_test (tc_chain, test_sdes_parsing_valid_single_item);
+ tcase_add_test (tc_chain, test_sdes_parsing_valid_in_compound_packet);
+ tcase_add_test (tc_chain,
test_sdes_add_item_bounds_check_in_compound_packet);
+ tcase_add_test (tc_chain, test_sdes_add_item_and_parse);
tcase_add_test (tc_chain,
test_sdes_parsing_valid_single_item_multiple_entries);
tcase_add_test (tc_chain, test_sdes_parsing_valid_multiple_items);
++++++ gst-plugins-base.obsinfo ++++++
--- /var/tmp/diff_new_pack.oGsJru/_old 2026-07-12 16:21:16.004227436 +0200
+++ /var/tmp/diff_new_pack.oGsJru/_new 2026-07-12 16:21:16.072229762 +0200
@@ -1,5 +1,5 @@
name: gst-plugins-base
-version: 1.28.4
-mtime: 1781266783
-commit: b46f881eaa8126eddfd21b5ae5512f8d4ff36255
+version: 1.28.5
+mtime: 1783546959
+commit: 727ceb91886862d200f423baf36cde2bb7ce5b4d