mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
bufferlist: Prevent gst_buffer_list_foreach() from modifying non-writeable lists
Previously gst_buffer_list_foreach() could modify (drop or replace) buffers in non-writable lists, which could cause all kinds of problems if other code also has a reference to the list and assumes that it stays the same. https://bugzilla.gnome.org/show_bug.cgi?id=796692
This commit is contained in:
parent
111faa58c0
commit
cb51bd6b31
2 changed files with 49 additions and 2 deletions
|
@ -247,7 +247,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
|
||||||
{
|
{
|
||||||
guint i, len;
|
guint i, len;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
gboolean list_was_writable;
|
gboolean list_was_writable, first_warning = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
|
g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
|
||||||
g_return_val_if_fail (func != NULL, FALSE);
|
g_return_val_if_fail (func != NULL, FALSE);
|
||||||
|
@ -281,7 +281,22 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
|
||||||
|
|
||||||
/* Check if the function changed the buffer */
|
/* Check if the function changed the buffer */
|
||||||
if (buf != buf_ret) {
|
if (buf != buf_ret) {
|
||||||
if (buf_ret == NULL) {
|
/* If the list was not writable but the callback was actually changing
|
||||||
|
* our buffer, then it wouldn't have been allowed to do so.
|
||||||
|
*
|
||||||
|
* Fortunately we still have a reference to the old buffer in that case
|
||||||
|
* and just not modify the list, unref the new buffer (if any) and warn
|
||||||
|
* about this */
|
||||||
|
if (!list_was_writable) {
|
||||||
|
if (first_warning) {
|
||||||
|
g_critical
|
||||||
|
("gst_buffer_list_foreach: non-writable list %p was changed from callback",
|
||||||
|
list);
|
||||||
|
first_warning = FALSE;
|
||||||
|
}
|
||||||
|
if (buf_ret)
|
||||||
|
gst_buffer_unref (buf_ret);
|
||||||
|
} else if (buf_ret == NULL) {
|
||||||
gst_buffer_list_remove_range_internal (list, i, 1, !was_writable);
|
gst_buffer_list_remove_range_internal (list, i, 1, !was_writable);
|
||||||
--len;
|
--len;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -508,6 +508,37 @@ GST_START_TEST (test_multiple_mutable_buffer_references)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
foreach_replace_buffer (GstBuffer ** buffer, guint idx, gpointer user_data)
|
||||||
|
{
|
||||||
|
gst_buffer_unref (*buffer);
|
||||||
|
*buffer = gst_buffer_new ();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_foreach_modify_non_writeable_list)
|
||||||
|
{
|
||||||
|
GstBufferList *b = gst_buffer_list_new_sized (1);
|
||||||
|
GstBuffer *buf;
|
||||||
|
|
||||||
|
buf = gst_buffer_new ();
|
||||||
|
gst_buffer_list_add (b, gst_buffer_ref (buf));
|
||||||
|
gst_buffer_list_ref (b);
|
||||||
|
|
||||||
|
fail_if (gst_buffer_list_is_writable (b));
|
||||||
|
|
||||||
|
ASSERT_CRITICAL (gst_buffer_list_foreach (b, foreach_replace_buffer, NULL));
|
||||||
|
|
||||||
|
fail_unless (gst_buffer_list_get (b, 0) == buf);
|
||||||
|
|
||||||
|
gst_buffer_list_unref (b);
|
||||||
|
gst_buffer_list_unref (b);
|
||||||
|
gst_buffer_unref (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_buffer_list_suite (void)
|
gst_buffer_list_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -527,6 +558,7 @@ gst_buffer_list_suite (void)
|
||||||
tcase_add_test (tc_chain, test_calc_size);
|
tcase_add_test (tc_chain, test_calc_size);
|
||||||
tcase_add_test (tc_chain, test_new_sized_0);
|
tcase_add_test (tc_chain, test_new_sized_0);
|
||||||
tcase_add_test (tc_chain, test_multiple_mutable_buffer_references);
|
tcase_add_test (tc_chain, test_multiple_mutable_buffer_references);
|
||||||
|
tcase_add_test (tc_chain, test_foreach_modify_non_writeable_list);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue