diff --git a/ChangeLog b/ChangeLog index f7379d5192..08e84fa4b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-07-31 Wim Taymans + + * gst/gstvalue.c: (gst_value_compare_list): + Fix GstValueList comparison code. Fixes #347293. + + * tests/check/gst/gstvalue.c: (GST_START_TEST): + Check to test GstValueList comparison. + 2006-07-31 Jan Schmidt * gst/gstelementfactory.c: (gst_element_factory_create): diff --git a/gst/gstvalue.c b/gst/gstvalue.c index f1748eb22b..887b087f78 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -465,22 +465,45 @@ gst_value_compare_list (const GValue * value1, const GValue * value2) GArray *array2 = value2->data[0].v_pointer; GValue *v1; GValue *v2; + gint len, to_remove; + guint8 *removed; - if (array1->len != array2->len) + /* get length and do initial length check. */ + len = array1->len; + if (len != array2->len) return GST_VALUE_UNORDERED; - for (i = 0; i < array1->len; i++) { - v1 = &g_array_index (array1, GValue, i); - for (j = 0; j < array1->len; j++) { - v2 = &g_array_index (array2, GValue, j); - if (gst_value_compare (v1, v2) == GST_VALUE_EQUAL) - break; - } - if (j == array1->len) { - return GST_VALUE_UNORDERED; - } - } + /* place to mark removed value indices of array2 */ + removed = g_newa (guint8, len); + memset (removed, 0, len); + to_remove = len; + /* loop over array1, all items should be in array2. When we find an + * item in array2, remove it from array2 by marking it as removed */ + for (i = 0; i < len; i++) { + v1 = &g_array_index (array1, GValue, i); + for (j = 0; j < len; j++) { + /* item is removed, we can skip it */ + if (removed[j]) + continue; + v2 = &g_array_index (array2, GValue, j); + if (gst_value_compare (v1, v2) == GST_VALUE_EQUAL) { + /* mark item as removed now that we found it in array2 and + * decrement the number of remaining items in array2. */ + removed[j] = 1; + to_remove--; + break; + } + } + /* item in array1 and not in array2, UNORDERED */ + if (j == len) + return GST_VALUE_UNORDERED; + } + /* if not all items were removed, array2 contained something not in array1 */ + if (to_remove != 0) + return GST_VALUE_UNORDERED; + + /* arrays are equal */ return GST_VALUE_EQUAL; } diff --git a/tests/check/gst/gstvalue.c b/tests/check/gst/gstvalue.c index 7303adeda6..b9c38beb40 100644 --- a/tests/check/gst/gstvalue.c +++ b/tests/check/gst/gstvalue.c @@ -590,6 +590,16 @@ GST_START_TEST (test_value_compare) fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL, "Value lists with different size were equal when they shouldn't be"); + /* Carry over the lists to this next check: */ + /* Lists with same size but list1 contains one more element not in list2 */ + g_value_set_int (&tmp, 5); + gst_value_list_append_value (&value1, &tmp); + + fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL, + "Value lists with different elements were equal when they shouldn't be"); + fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL, + "Value lists with different elements were equal when they shouldn't be"); + g_value_unset (&value1); g_value_unset (&value2); g_value_unset (&tmp); @@ -634,6 +644,9 @@ GST_START_TEST (test_value_compare) fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL, "Value arrays with different size were equal when they shouldn't be"); + /* order should not matter */ + fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL, + "Value arrays with different size were equal when they shouldn't be"); g_value_unset (&value1); g_value_unset (&value2);