From 03f7c8c30478160357c55a18f82fa55e1b31d31a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 May 2013 13:47:10 +0200 Subject: [PATCH] Fix several memory leaks. --- ChangeLog | 4 +++ grub-core/gfxmenu/font.c | 2 ++ grub-core/gfxmenu/gfxmenu.c | 2 +- grub-core/gfxmenu/gui_list.c | 5 ++- grub-core/gfxmenu/gui_progress_bar.c | 1 + grub-core/normal/context.c | 2 ++ grub-core/normal/main.c | 2 ++ grub-core/normal/menu_entry.c | 10 +++++- grub-core/normal/menu_text.c | 5 ++- grub-core/normal/term.c | 2 ++ grub-core/term/gfxterm.c | 47 ++++++++++++++++++++++------ grub-core/tests/lib/test.c | 3 +- grub-core/video/capture.c | 1 + 13 files changed, 72 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b0576d93..47f06fdc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-05-04 Vladimir Serbinenko + + Fix several memory leaks. + 2013-05-04 Vladimir Serbinenko * grub-core/normal/menu.c (run_menu): Fix timeout reference point. diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c index 4a8e1f11e..9c6e2d491 100644 --- a/grub-core/gfxmenu/font.c +++ b/grub-core/gfxmenu/font.c @@ -70,6 +70,8 @@ grub_font_draw_string (const char *str, grub_font_t font, return err; } + for (ptr = visual; ptr < visual + visual_len; ptr++) + grub_free (ptr->combining); grub_free (visual); return GRUB_ERR_NONE; diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 51110a6f8..f49fce802 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -85,7 +85,7 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) || cached_view->screen.width != mode_info.width || cached_view->screen.height != mode_info.height) { - grub_free (cached_view); + grub_gfxmenu_view_destroy (cached_view); /* Create the view. */ cached_view = grub_gfxmenu_view_new (full_theme_path ? : theme_path, mode_info.width, diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index a06603b0b..1a2a16d32 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -83,7 +83,10 @@ list_destroy (void *vself) self->selected_item_box->destroy (self->selected_item_box); if (self->icon_manager) grub_gfxmenu_icon_manager_destroy (self->icon_manager); - + if (self->scrollbar_thumb) + self->scrollbar_thumb->destroy (self->scrollbar_thumb); + if (self->scrollbar_frame) + self->scrollbar_frame->destroy (self->scrollbar_frame); grub_free (self); } diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c index 965c6b386..cb709302b 100644 --- a/grub-core/gfxmenu/gui_progress_bar.c +++ b/grub-core/gfxmenu/gui_progress_bar.c @@ -185,6 +185,7 @@ draw_text (grub_gui_progress_bar_t self) int y = ((height - grub_font_get_descent (font)) / 2 + grub_font_get_ascent (font) / 2); grub_font_draw_string (text, font, text_color, x, y); + grub_free (text); } } diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index e9923ccdc..7e0a696f3 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -139,6 +139,8 @@ grub_env_context_close (void) grub_current_context = context; menu = current_menu->prev; + if (current_menu->menu) + grub_normal_free_menu (current_menu->menu); grub_free (current_menu); current_menu = menu; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 759e0a4c4..f7a815fa1 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -127,6 +127,7 @@ grub_normal_free_menu (grub_menu_t menu) grub_free ((void *) entry->users); grub_free ((void *) entry->title); grub_free ((void *) entry->sourcecode); + grub_free (entry); entry = next_entry; } @@ -191,6 +192,7 @@ read_config_file (const char *config) if (ptr) *ptr = 0; grub_env_set ("config_directory", config_dir); + grub_free (config_dir); grub_env_export ("config_file"); grub_env_export ("config_directory"); diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index e0407aa88..3cc0c0113 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -517,7 +517,15 @@ destroy_screen (struct screen *screen) struct line *linep = screen->lines + i; if (linep) - grub_free (linep->buf); + { + unsigned j; + if (linep->pos) + for (j = 0; j < screen->nterms; j++) + grub_free (linep->pos[j]); + + grub_free (linep->buf); + grub_free (linep->pos); + } } grub_free (screen->killed_text); diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c index e1d3c8fcb..19a538930 100644 --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -56,8 +56,10 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, while (str < last_position) { struct grub_unicode_glyph glyph; + glyph.combining = 0; str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph); width += grub_term_getcharwidth (term, &glyph); + grub_free (glyph.combining); } return width; } @@ -396,6 +398,7 @@ menu_text_print_timeout (int timeout, void *dataptr) } grub_print_message_indented (msg_translated, 3, 0, data->term); + grub_free (msg_translated); posx = grub_term_getxy (data->term) >> 8; grub_print_spaces (data->term, grub_term_width (data->term) - posx - 1); @@ -447,7 +450,7 @@ menu_text_fini (void *dataptr) grub_term_setcursor (data->term, 1); grub_term_cls (data->term); - + grub_free (data); } static void diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 976442382..820156f48 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -952,6 +952,8 @@ print_ucs4_real (const grub_uint32_t * str, ret++; if (visual_len_show && visual[visual_len_show - 1].base != '\n') ret++; + for (vptr = visual; vptr < visual + visual_len; vptr++) + grub_free (vptr->combining); grub_free (visual); } else diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index a168e01cf..1e33a34b3 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -175,7 +175,11 @@ set_term_color (grub_uint8_t term_color) static void clear_char (struct grub_colored_char *c) { - grub_free (c->code); + if (c->code) + { + grub_free (c->code->combining); + grub_free (c->code); + } c->code = grub_unicode_glyph_from_code (' '); if (!c->code) grub_errno = GRUB_ERR_NONE; @@ -188,7 +192,18 @@ grub_virtual_screen_free (void) { /* If virtual screen has been allocated, free it. */ if (virtual_screen.text_buffer != 0) - grub_free (virtual_screen.text_buffer); + { + unsigned i; + for (i = 0; + i < virtual_screen.columns * virtual_screen.rows; + i++) + if (virtual_screen.text_buffer[i].code) + { + grub_free (virtual_screen.text_buffer[i].code->combining); + grub_free (virtual_screen.text_buffer[i].code); + } + grub_free (virtual_screen.text_buffer); + } /* Reset virtual screen data. */ grub_memset (&virtual_screen, 0, sizeof (virtual_screen)); @@ -403,7 +418,11 @@ grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused))) for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) { - grub_free (virtual_screen.text_buffer[i].code); + if (virtual_screen.text_buffer[i].code) + { + grub_free (virtual_screen.text_buffer[i].code->combining); + grub_free (virtual_screen.text_buffer[i].code); + } virtual_screen.text_buffer[i].code = 0; } @@ -798,7 +817,11 @@ scroll_up (void) /* Clear first line in text buffer. */ for (i = 0; i < virtual_screen.columns; i++) - grub_free (virtual_screen.text_buffer[i].code); + if (virtual_screen.text_buffer[i].code) + { + grub_free (virtual_screen.text_buffer[i].code->combining); + grub_free (virtual_screen.text_buffer[i].code); + } /* Scroll text buffer with one line to up. */ grub_memmove (virtual_screen.text_buffer, @@ -874,7 +897,11 @@ grub_gfxterm_putchar (struct grub_term_output *term, p = (virtual_screen.text_buffer + virtual_screen.cursor_x + virtual_screen.cursor_y * virtual_screen.columns); - grub_free (p->code); + if (p->code) + { + grub_free (p->code->combining); + grub_free (p->code); + } p->code = grub_unicode_glyph_dup (c); if (!p->code) grub_errno = GRUB_ERR_NONE; @@ -889,10 +916,12 @@ grub_gfxterm_putchar (struct grub_term_output *term, for (i = 1; i < char_width && p + i < virtual_screen.text_buffer + virtual_screen.columns * virtual_screen.rows; i++) - { - grub_free (p[i].code); - p[i].code = NULL; - } + if (p[i].code) + { + grub_free (p[i].code->combining); + grub_free (p[i].code); + p[i].code = NULL; + } } /* Draw glyph. */ diff --git a/grub-core/tests/lib/test.c b/grub-core/tests/lib/test.c index 1d2cb8c6e..3000fc88d 100644 --- a/grub-core/tests/lib/test.c +++ b/grub-core/tests/lib/test.c @@ -87,7 +87,8 @@ failure_append_vtext(grub_test_failure_t failure, const char *fmt, va_list args) char *oldmsg = failure->message; failure->message = grub_xasprintf("%s%s", oldmsg, msg); - grub_free(oldmsg); + grub_free (oldmsg); + grub_free (msg); } else { diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c index be7fb61af..18ffa28e3 100644 --- a/grub-core/video/capture.c +++ b/grub-core/video/capture.c @@ -115,6 +115,7 @@ grub_video_capture_get_framebuffer (void) void grub_video_capture_end (void) { + grub_video_fb_delete_render_target (framebuffer.render_target); grub_free (framebuffer.ptr); grub_video_fb_fini (); grub_video_adapter_active = saved;