summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2016-08-24 19:43:51 -0300
committerVitor Sousa <vitorsousasilva@gmail.com>2016-08-26 19:45:26 -0300
commit5d2948b016955410ca8137ec944b8b91b169dc07 (patch)
treeb0a58041163afaf86a2d919b7af5d7cc2b8d98b7
parent1ab1e3697dc4dfead65fadc02747d876c993f935 (diff)
elm fileselector: fix possible premature deletion of Listing_Request struct
In a case where eina_promise_then is executed immediately (like with some quick and light Efl.Model), the Listing_Request struct will be prematurely freed in the first iteration of the child processing loop, because the item_total counter had not accumulated the right number of items yet. With this commit, we traverse the children accessor first, so we can know the number of items. Also, no longer use the Listing_Request pointer after the loop, once it may have been deallocate already. And put a note about this too.
-rw-r--r--src/lib/elementary/elc_fileselector.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/lib/elementary/elc_fileselector.c b/src/lib/elementary/elc_fileselector.c
index ec30015fb3..21bf9c4f65 100644
--- a/src/lib/elementary/elc_fileselector.c
+++ b/src/lib/elementary/elc_fileselector.c
@@ -774,7 +774,17 @@ _process_child_error_cb(void *data, Eina_Error err EINA_UNUSED)
774 774
775 ERR("Failed to access to a model property"); 775 ERR("Failed to access to a model property");
776 776
777 lreq->item_total--; 777 ++(lreq->item_processed_count);
778 if (lreq->item_processed_count >= lreq->item_total)
779 {
780 if (!lreq->valid)
781 {
782 _listing_request_cleanup(lreq);
783 return;
784 }
785 _signal_first(lreq);
786 _process_last(lreq);
787 }
778} 788}
779 789
780static void 790static void
@@ -800,8 +810,7 @@ _process_children_cb(void *data, void *values)
800 Elm_Fileselector_Item_Data *it_data = NULL; 810 Elm_Fileselector_Item_Data *it_data = NULL;
801 const char *path = NULL; 811 const char *path = NULL;
802 const char *selected_path = NULL; 812 const char *selected_path = NULL;
803 void *child = NULL; 813 unsigned int count = 0;
804 unsigned int i = 0;
805 Elm_Fileselector_Data *sd = lreq->sd; 814 Elm_Fileselector_Data *sd = lreq->sd;
806 815
807 if (!lreq->valid) 816 if (!lreq->valid)
@@ -829,7 +838,16 @@ _process_children_cb(void *data, void *values)
829 lreq->path = eina_stringshare_add(path); 838 lreq->path = eina_stringshare_add(path);
830 if (children_accessor) 839 if (children_accessor)
831 { 840 {
832 EINA_ACCESSOR_FOREACH(children_accessor, i, child) 841 Eina_List *children = NULL;
842 void *child = NULL;
843 EINA_ACCESSOR_FOREACH(children_accessor, count, child)
844 {
845 children = eina_list_append(children, child);
846 }
847
848 lreq->item_total = count;
849
850 EINA_LIST_FREE(children, child)
833 { 851 {
834 Eina_Promise *promises[7]; 852 Eina_Promise *promises[7];
835 Eina_Promise *promise_all = NULL; 853 Eina_Promise *promise_all = NULL;
@@ -862,11 +880,13 @@ _process_children_cb(void *data, void *values)
862 promises[6] = NULL; 880 promises[6] = NULL;
863 881
864 promise_all = eina_promise_all(eina_carray_iterator_new((void**)promises)); 882 promise_all = eina_promise_all(eina_carray_iterator_new((void**)promises));
865 ++(lreq->item_total);
866 eina_promise_then(promise_all, _process_child_cb, _process_child_error_cb, it_data); 883 eina_promise_then(promise_all, _process_child_cb, _process_child_error_cb, it_data);
867 } 884 }
885
886 // NOTE: lreq may have been deallocated in the previous loop
887 lreq = NULL;
868 } 888 }
869 if (lreq->item_total == 0) 889 if (count == 0)
870 { 890 {
871 _signal_first(lreq); 891 _signal_first(lreq);
872 _process_last(lreq); 892 _process_last(lreq);