From ab9256adf082ce78cfb39eb246323e57b846a7a4 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Tue, 27 Sep 2016 18:52:13 +0200 Subject: Fix out-of-bounds memory access Do not try to access freed day items. This also fixes unexpected selection changes after modifying appointments or events. Signed-off-by: Lukas Fleischer --- src/calcurse.c | 11 ++++++++++- src/calcurse.h | 2 ++ src/day.c | 9 +++++++-- src/ui-day.c | 9 +++++++-- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/calcurse.c b/src/calcurse.c index c0d9624..89710af 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -49,6 +49,15 @@ int count, reg; static void do_storage(int day_changed) { struct day_item *day = ui_day_selitem(); + union aptev_ptr item; + + if (day) { + /* + * day_process_storage() rebuilds the vector of day items, so + * we need to save the reference to the actual item here. + */ + item = day->item; + } day_process_storage(ui_calendar_get_slctd_day(), day_changed); ui_day_load_items(); @@ -56,7 +65,7 @@ static void do_storage(int day_changed) if (day_changed) ui_day_sel_reset(); else if (day) - ui_day_set_selitem(day); + ui_day_set_selitem_by_aptev_ptr(item); } static inline void key_generic_change_view(void) diff --git a/src/calcurse.h b/src/calcurse.h index 3aab885..c8f7bb9 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -772,6 +772,7 @@ int day_check_if_item(struct date); unsigned day_chk_busy_slices(struct date, int, int *); struct day_item *day_cut_item(long, int); int day_paste_item(struct day_item *, long); +int day_get_position_by_aptev_ptr(union aptev_ptr); int day_get_position(struct day_item *); struct day_item *day_get_item(int); unsigned day_item_count(int); @@ -1044,6 +1045,7 @@ void todo_free_list(void); /* ui-day.c */ struct day_item *ui_day_selitem(void); +void ui_day_set_selitem_by_aptev_ptr(union aptev_ptr); void ui_day_set_selitem(struct day_item *); void ui_day_item_add(void); void ui_day_item_delete(unsigned); diff --git a/src/day.c b/src/day.c index 2bd4a31..970e8ff 100644 --- a/src/day.c +++ b/src/day.c @@ -695,20 +695,25 @@ int day_paste_item(struct day_item *p, long date) } /* Returns the position corresponding to a given item. */ -int day_get_position(struct day_item *needle) +int day_get_position_by_aptev_ptr(union aptev_ptr aptevp) { int n = 0; VECTOR_FOREACH(&day_items, n) { struct day_item *p = VECTOR_NTH(&day_items, n); /* Compare pointers. */ - if (p->item.ev == needle->item.ev) + if (p->item.ev == aptevp.ev) return n; } return -1; } +int day_get_position(struct day_item *needle) +{ + return day_get_position_by_aptev_ptr(needle->item); +} + /* Returns a structure containing the selected item. */ struct day_item *day_get_item(int item_number) { diff --git a/src/ui-day.c b/src/ui-day.c index 6eb055e..c8a4420 100644 --- a/src/ui-day.c +++ b/src/ui-day.c @@ -46,13 +46,18 @@ struct day_item *ui_day_selitem(void) return day_get_item(listbox_get_sel(&lb_apt)); } -void ui_day_set_selitem(struct day_item *day) +void ui_day_set_selitem_by_aptev_ptr(union aptev_ptr p) { - int n = day_get_position(day); + int n = day_get_position_by_aptev_ptr(p); if (n >= 0) listbox_set_sel(&lb_apt, n); } +void ui_day_set_selitem(struct day_item *day) +{ + ui_day_set_selitem_by_aptev_ptr(day->item); +} + /* Request the user to enter a new time. */ static int day_edit_time(int time, unsigned *new_hour, unsigned *new_minute) -- cgit v1.2.3-54-g00ecf