efl: `eina_value_list_vinsert` assumes that the position is always valid
authorLucas Cavalcante de Sousa <lucas@expertisesolutions.com.br>
Fri, 7 Feb 2020 18:52:15 +0000 (13:52 -0500)
committerJongmin Lee <jm105.lee@samsung.com>
Tue, 11 Feb 2020 22:00:06 +0000 (07:00 +0900)
Summary:
The eina_value_list_vinsert at src/lib/eina_inline_value.x was not checking if the desired position was valid:
When inserting in an empty list in any out of bounds position it actually createded a list with the head being the desired value.
When inserting in a non-empty list in an out of bounds position caused a c error.
Now both cases return EINA_FALSE

Ref T8611

Test Plan:
Meson configured with -Dbindings=mono,cxx -Dmono-beta=true, and tests runned
with ninja test all.

Reviewers: felipealmeida, zmike

Reviewed By: zmike

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8611

Differential Revision: https://phab.enlightenment.org/D11301

src/lib/eina/eina_inline_value.x
src/tests/eina/eina_test_value.c

index 8d3457c..904192c 100644 (file)
@@ -979,13 +979,14 @@ eina_value_list_vinsert(Eina_Value *value, unsigned int position, va_list args)
    if (!desc)
      return EINA_FALSE;
 
-   if (!desc->list)
+   if (!desc->list && position == 0)
      node = desc->list = eina_list_append(NULL, (void*)1L);
    else if (position == 0)
      node = desc->list = eina_list_prepend(desc->list, (void*)1L);
    else
      {
         Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
+        EINA_SAFETY_ON_FALSE_RETURN_VAL(rel, EINA_FALSE);
         desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
         node = rel->next;
      }
@@ -1734,7 +1735,7 @@ eina_value_optional_type_get(Eina_Value *value)
    mem = eina_value_memory_get(value);
    if (!mem)
      return NULL;
-   
+
    if(2*sizeof(void*) <= sizeof(Eina_Value_Union))
      {
        Eina_Value_Optional_Outer* opt = (Eina_Value_Optional_Outer*)mem;
index 347c79b..7d9e27e 100644 (file)
@@ -2158,6 +2158,48 @@ EFL_START_TEST(eina_value_test_array)
 }
 EFL_END_TEST
 
+EFL_START_TEST(eina_value_test_list_insert)
+{
+   Eina_Value *value;
+   char c;
+   char *str;
+   char buf[1024];
+
+   value = eina_value_list_new(EINA_VALUE_TYPE_CHAR);
+   fail_unless(value != NULL);
+
+   fail_unless(eina_value_list_count(value) == 0);
+   fail_unless(!eina_value_list_insert(value, 1, '-'));
+   fail_unless(!eina_value_list_insert(value, 10, 'j'));
+   fail_unless(eina_value_list_count(value) == 0);
+
+   fail_unless(eina_value_list_insert(value, 0, 'k'));
+   fail_unless(eina_value_list_insert(value, 1, '-'));
+   fail_unless(eina_value_list_insert(value, 0, 's'));
+   fail_unless(eina_value_list_insert(value, 1, 'j'));
+   fail_unless(eina_value_list_count(value) == 4);
+
+   fail_unless(eina_value_list_get(value, 0, &c));
+   fail_unless(c == 's');
+   fail_unless(eina_value_list_get(value, 1, &c));
+   fail_unless(c == 'j');
+   fail_unless(eina_value_list_get(value, 2, &c));
+   fail_unless(c == 'k');
+   fail_unless(eina_value_list_get(value, 3, &c));
+   fail_unless(c == '-');
+
+   snprintf(buf, sizeof(buf), "[%d, %d, %d, %d]",
+            (int) 's', (int) 'j', (int) 'k', (int) '-');
+
+   str = eina_value_to_string(value);
+   fail_unless(str != NULL);
+   ck_assert_str_eq(str, buf);
+
+   free(str);
+   eina_value_free(value);
+}
+EFL_END_TEST
+
 EFL_START_TEST(eina_value_test_list)
 {
    Eina_Value *value, other;
@@ -3031,6 +3073,7 @@ eina_test_value(TCase *tc)
    // TODO: other converters...
    tcase_add_test(tc, eina_value_test_array);
    tcase_add_test(tc, eina_value_test_list);
+   tcase_add_test(tc, eina_value_test_list_insert);
    tcase_add_test(tc, eina_value_test_hash);
    tcase_add_test(tc, eina_value_test_timeval);
    tcase_add_test(tc, eina_value_test_blob);