From 2619a59f82366fd0117ed6ccceb586633f59e978 Mon Sep 17 00:00:00 2001 From: Jordan Yelloz Date: Mon, 27 Jan 2025 07:45:22 -0700 Subject: [PATCH] gstiterator: Added error handling to filtered iterators Otherwise, if the underlying iterator returns GST_ITERATOR_ERROR, the filtered iterator will crash. With this change, the filtered iterator propagates the error back to the caller. Part-of: --- subprojects/gstreamer/gst/gstiterator.c | 1 + .../gstreamer/tests/check/gst/gstiterator.c | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/subprojects/gstreamer/gst/gstiterator.c b/subprojects/gstreamer/gst/gstiterator.c index 870f5807d3..db0f597fd5 100644 --- a/subprojects/gstreamer/gst/gstiterator.c +++ b/subprojects/gstreamer/gst/gstiterator.c @@ -486,6 +486,7 @@ filter_next (GstIteratorFilter * it, GValue * elem) break; case GST_ITERATOR_RESYNC: case GST_ITERATOR_DONE: + case GST_ITERATOR_ERROR: done = TRUE; break; default: diff --git a/subprojects/gstreamer/tests/check/gst/gstiterator.c b/subprojects/gstreamer/tests/check/gst/gstiterator.c index 9e989f8682..50043602c5 100644 --- a/subprojects/gstreamer/tests/check/gst/gstiterator.c +++ b/subprojects/gstreamer/tests/check/gst/gstiterator.c @@ -37,6 +37,41 @@ make_list_of_ints (gint n) return g_list_reverse (ret); } +static GstIteratorResult +broken_iterator_next (G_GNUC_UNUSED GstIterator * it, + G_GNUC_UNUSED GValue * val) +{ + return GST_ITERATOR_ERROR; +} + +static void +broken_iterator_resync (G_GNUC_UNUSED GstIterator * it) +{ +} + +static void +broken_iterator_free (G_GNUC_UNUSED GstIterator * it) +{ +} + +static GstIterator * +make_broken_iterator (GType item_type, GMutex * mutex, guint32 * cookie) +{ + return gst_iterator_new (sizeof (GstIterator), + item_type, + mutex, + cookie, + NULL, + broken_iterator_next, NULL, broken_iterator_resync, broken_iterator_free); +} + +static gint +passthrough_filter (G_GNUC_UNUSED gconstpointer a, + G_GNUC_UNUSED gconstpointer b) +{ + return 0; +} + #define NUM_ELEMENTS 10 GST_START_TEST (test_manual_iteration) @@ -424,6 +459,28 @@ GST_START_TEST (test_filter_of_filter_locking) GST_END_TEST; +GST_START_TEST (test_filter_propagates_error) +{ + guint32 cookie = 0; + GMutex m; + g_mutex_init (&m); + + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_POINTER); + + GstIterator *it = + gst_iterator_filter (make_broken_iterator (G_TYPE_POINTER, &mutex, + &cookie), passthrough_filter, NULL); + + fail_unless_equals_int (gst_iterator_next (it, &v), GST_ITERATOR_ERROR); + + gst_iterator_free (it); + g_mutex_clear (&m); + g_value_unset (&v); +} + +GST_END_TEST; + static Suite * gst_iterator_suite (void) { @@ -441,6 +498,7 @@ gst_iterator_suite (void) tcase_add_test (tc_chain, test_filter_locking); tcase_add_test (tc_chain, test_filter_of_filter); tcase_add_test (tc_chain, test_filter_of_filter_locking); + tcase_add_test (tc_chain, test_filter_propagates_error); return s; }