From 3e5c15a9a303619657027f7fe8c5021669ec82f4 Mon Sep 17 00:00:00 2001 From: Felix Kratz Date: Sat, 25 Dec 2021 20:45:06 +0100 Subject: [PATCH] Fix some pesky leaks, now close to leak free. Co-authored-by: LeonHeidelbach --- makefile | 10 +++++++++- src/alias.c | 7 +++++++ src/alias.h | 1 + src/bar_item.c | 31 ++++++++++++++++++++----------- src/bar_manager.c | 20 ++++++++++++-------- src/bar_manager.h | 5 +++-- src/custom_events.c | 19 ++++++++++++++++++- src/custom_events.h | 1 + src/message.c | 7 +++++-- src/message.h | 2 ++ src/misc/helpers.h | 4 +++- src/text.c | 3 ++- 12 files changed, 83 insertions(+), 27 deletions(-) diff --git a/makefile b/makefile index 4229d8d..811d790 100644 --- a/makefile +++ b/makefile @@ -25,8 +25,16 @@ uninstall: clean profile: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -g -Ofast -fvisibility=hidden profile: clean $(x86_BINS) -debug: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -fsanitize=address -fsanitize=undefined -g -O0 -fvisibility=hidden +leak: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -g +leak: clean $(ARM_BINS) + /usr/libexec/PlistBuddy -c "Add :com.apple.security.get-task-allow bool true" bin/tmp.entitlements + codesign -s - --entitlements bin/tmp.entitlements -f ./bin/sketchybar_arm + leaks -atExit -- ./bin/sketchybar_arm + + +debug: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer debug: clean $(ARM_BINS) + ./bin/sketchybar_arm update: clean $(UNIVERSAL_BINS) rm /usr/local/bin/sketchybar diff --git a/src/alias.c b/src/alias.c index 16a6938..639f1b7 100644 --- a/src/alias.c +++ b/src/alias.c @@ -181,6 +181,13 @@ void alias_draw(struct alias* alias, CGContextRef context) { CGContextDrawImage(context, alias->bounds, alias->image_ref); } +void alias_destroy(struct alias* alias) { + CGImageRelease(alias->image_ref); + if (alias->data_ref) CFRelease(alias->data_ref); + if (alias->name) free(alias->name); + if (alias->owner) free(alias->owner); +} + void alias_calculate_bounds(struct alias* alias, uint32_t x, uint32_t y) { alias->bounds.origin.x = x; alias->bounds.origin.y = y - alias->bounds.size.height / 2; diff --git a/src/alias.h b/src/alias.h index c62557e..efbd6f2 100644 --- a/src/alias.h +++ b/src/alias.h @@ -25,5 +25,6 @@ uint32_t alias_get_height(struct alias* alias); void alias_calculate_bounds(struct alias* alias, uint32_t x, uint32_t y); void alias_draw(struct alias* alias, CGContextRef context); +void alias_destroy(struct alias* alias); #endif diff --git a/src/bar_item.c b/src/bar_item.c index 760815f..0341dc0 100644 --- a/src/bar_item.c +++ b/src/bar_item.c @@ -52,6 +52,7 @@ void bar_item_inherit_from_item(struct bar_item* bar_item, struct bar_item* ance bar_item_set_click_script(bar_item, string_copy(ancestor->click_script)); if (bar_item->type == BAR_COMPONENT_SPACE) { + env_vars_set(&bar_item->signal_args.env_vars, string_copy("SELECTED"), string_copy("false")); env_vars_set(&bar_item->signal_args.env_vars, string_copy("SID"), string_copy(env_vars_get_value_for_key(&ancestor->signal_args.env_vars, "DID"))); env_vars_set(&bar_item->signal_args.env_vars, string_copy("DID"), string_copy(env_vars_get_value_for_key(&ancestor->signal_args.env_vars, "DID"))); } @@ -97,8 +98,6 @@ void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) { popup_init(&bar_item->popup); if (default_item) bar_item_inherit_from_item(bar_item, default_item); - - env_vars_set(&bar_item->signal_args.env_vars, string_copy("SELECTED"), string_copy("false")); } void bar_item_append_associated_space(struct bar_item* bar_item, uint32_t bit) { @@ -183,7 +182,7 @@ void bar_item_clear_needs_update(struct bar_item* bar_item) { void bar_item_set_name(struct bar_item* bar_item, char* name) { if (!name) return; if (bar_item->name && strcmp(bar_item->name, name) == 0) { free(name); return; } - if (name != bar_item->name && !bar_item->name) free(bar_item->name); + if (name != bar_item->name && bar_item->name) free(bar_item->name); bar_item->name = name; env_vars_set(&bar_item->signal_args.env_vars, string_copy("NAME"), string_copy(name)); } @@ -198,6 +197,7 @@ void bar_item_set_type(struct bar_item* bar_item, char type) { bar_item->update_mask |= UPDATE_SPACE_CHANGE; bar_item->updates = false; + env_vars_set(&bar_item->signal_args.env_vars, string_copy("SELECTED"), string_copy("false")); env_vars_set(&bar_item->signal_args.env_vars, string_copy("SID"), string_copy("0")); env_vars_set(&bar_item->signal_args.env_vars, string_copy("DID"), string_copy("0")); } @@ -220,17 +220,23 @@ void bar_item_set_type(struct bar_item* bar_item, char type) { void bar_item_set_script(struct bar_item* bar_item, char* script) { if (!script) return; if (bar_item->script && strcmp(bar_item->script, script) == 0) { free(script); return; } - if (script != bar_item->script && !bar_item->script) free(bar_item->script); - if (bar_item->cache_scripts && file_exists(resolve_path(script))) bar_item->script = read_file(resolve_path(script)); - else bar_item->script = script; + if (script != bar_item->script && bar_item->script) free(bar_item->script); + char* path = resolve_path(script); + if (bar_item->cache_scripts && file_exists(path)) { + bar_item->script = read_file(path); + } + else bar_item->script = path; } void bar_item_set_click_script(struct bar_item* bar_item, char* script) { if (!script) return; if (bar_item->click_script && strcmp(bar_item->click_script, script) == 0) { free(script); return; } - if (script != bar_item->click_script && !bar_item->click_script) free(bar_item->click_script); - if (bar_item->cache_scripts && file_exists(resolve_path(script))) bar_item->click_script = read_file(resolve_path(script)); - else bar_item->click_script = script; + if (script != bar_item->click_script && bar_item->click_script) free(bar_item->click_script); + char* path = resolve_path(script); + if (bar_item->cache_scripts && file_exists(path)) { + bar_item->click_script = read_file(path); + } + else bar_item->click_script = path; } void bar_item_set_drawing(struct bar_item* bar_item, bool state) { @@ -370,8 +376,8 @@ void bar_item_draw(struct bar_item* bar_item, CGContextRef context) { void bar_item_destroy(struct bar_item* bar_item) { if (bar_item->name) free(bar_item->name); - if (bar_item->script && !bar_item->cache_scripts) free(bar_item->script); - if (bar_item->click_script && !bar_item->cache_scripts) free(bar_item->click_script); + if (bar_item->script) free(bar_item->script); + if (bar_item->click_script) free(bar_item->click_script); text_destroy(&bar_item->icon); text_destroy(&bar_item->label); @@ -385,6 +391,9 @@ void bar_item_destroy(struct bar_item* bar_item) { if (bar_item->has_graph) { graph_destroy(&bar_item->graph); } + if (bar_item->has_alias) { + alias_destroy(&bar_item->alias); + } if (bar_item->group && bar_item->type == BAR_COMPONENT_GROUP) group_destroy(bar_item->group); else if (bar_item->group) group_remove_member(bar_item->group, bar_item); env_vars_destroy(&bar_item->signal_args.env_vars); diff --git a/src/bar_manager.c b/src/bar_manager.c index 98753d7..10f8e8b 100644 --- a/src/bar_manager.c +++ b/src/bar_manager.c @@ -281,14 +281,6 @@ struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager) { return bar_item; } -void bar_manager_destroy_item(struct bar_manager* bar_manager, struct bar_item* bar_item) { - int index = bar_manager_get_item_index_by_address(bar_manager, bar_item); - memmove(bar_manager->bar_items + index, bar_manager->bar_items + index + 1, bar_manager->bar_item_count - index - 1); - bar_manager->bar_items = (struct bar_item**) realloc(bar_manager->bar_items, sizeof(struct bar_item*) * (bar_manager->bar_item_count - 1)); - bar_manager->bar_item_count -= 1; - bar_item_destroy(bar_item); -} - void bar_manager_update_alias_components(struct bar_manager* bar_manager, bool forced) { for (int i = 0; i < bar_manager->bar_item_count; i++) { if ((!bar_item_is_shown(bar_manager->bar_items[i]) && !forced) || bar_manager->bar_items[i]->type != BAR_COMPONENT_ALIAS) continue; @@ -435,6 +427,18 @@ void bar_manager_handle_notification(struct bar_manager* bar_manager, char* cont bar_manager_custom_events_trigger(bar_manager, name, NULL); } +void bar_manager_destroy(struct bar_manager* bar_manager) { + for (int i = 0; i < bar_manager->bar_item_count; i++) { + bar_item_destroy(bar_manager->bar_items[i]); + } + if (bar_manager->bar_items) free(bar_manager->bar_items); + for (int i = 0; i < bar_manager->bar_count; i++) { + bar_destroy(bar_manager->bars[i]); + } + custom_events_destroy(&bar_manager->custom_events); + if (bar_manager->bars) free(bar_manager->bars); +} + void bar_manager_serialize(struct bar_manager* bar_manager, FILE* rsp) { fprintf(rsp, "{\n" "\t\"geometry\": {\n" diff --git a/src/bar_manager.h b/src/bar_manager.h index 9c2305b..c05ca74 100644 --- a/src/bar_manager.h +++ b/src/bar_manager.h @@ -20,9 +20,9 @@ struct bar_manager { uint32_t window_level; CFRunLoopTimerRef refresh_timer; CFRunLoopTimerRef shell_refresh_timer; - struct bar **bars; + struct bar** bars; int bar_count; - struct bar_item **bar_items; + struct bar_item** bar_items; struct bar_item default_item; int bar_item_count; char position; @@ -82,6 +82,7 @@ void bar_manager_handle_space_change(struct bar_manager* bar_manager); void bar_manager_handle_display_change(struct bar_manager* bar_manager); void bar_manager_handle_system_woke(struct bar_manager* bar_manager); void bar_manager_handle_system_will_sleep(struct bar_manager* bar_manager); +void bar_manager_destroy(struct bar_manager* bar_manager); struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager, CGPoint point, uint32_t sid); diff --git a/src/custom_events.c b/src/custom_events.c index 5ba266f..45dc7cc 100644 --- a/src/custom_events.c +++ b/src/custom_events.c @@ -7,6 +7,12 @@ void custom_event_init(struct custom_event* custom_event, char* name, char* noti custom_event->notification = notification; } +void custom_event_destroy(struct custom_event* custom_event) { + if (custom_event->name) free(custom_event->name); + if (custom_event->notification) free(custom_event->notification); + free(custom_event); +} + void custom_events_init(struct custom_events* custom_events) { custom_events->count = 0; @@ -22,7 +28,11 @@ void custom_events_init(struct custom_events* custom_events) { } void custom_events_append(struct custom_events* custom_events, char* name, char* notification) { - if (custom_events_get_flag_for_name(custom_events, name) > 0) return; + if (custom_events_get_flag_for_name(custom_events, name) > 0) { + if (name) free(name); + if (notification) free(notification); + return; + } custom_events->count++; custom_events->events = (struct custom_event**) realloc(custom_events->events, sizeof(struct custom_event*) * custom_events->count); custom_events->events[custom_events->count - 1] = custom_event_create(); @@ -51,6 +61,13 @@ char* custom_events_get_name_for_notification(struct custom_events* custom_event return NULL; } +void custom_events_destroy(struct custom_events* custom_events) { + for (int i = 0; i < custom_events->count; i++) { + custom_event_destroy(custom_events->events[i]); + } + free(custom_events->events); +} + void custom_events_serialize(struct custom_events* custom_events, FILE* rsp) { fprintf(rsp, "{\n"); for (int i = 0; i < custom_events->count; i++) { diff --git a/src/custom_events.h b/src/custom_events.h index e33882d..76b647b 100644 --- a/src/custom_events.h +++ b/src/custom_events.h @@ -27,5 +27,6 @@ void custom_events_init(struct custom_events* custom_events); void custom_events_append(struct custom_events* custom_events, char* name, char* notification); uint64_t custom_events_get_flag_for_name(struct custom_events* custom_events, char* name); char* custom_events_get_name_for_notification(struct custom_events* custom_events, char* notification); +void custom_events_destroy(struct custom_events* custom_events); void custom_events_serialize(struct custom_events* custom_events, FILE* rsp); #endif diff --git a/src/message.c b/src/message.c index 92690df..a3b96cd 100644 --- a/src/message.c +++ b/src/message.c @@ -240,9 +240,9 @@ static void message_parse_set_message_for_bar_item(FILE* rsp, struct bar_item* b } needs_update = true; } else if (token_equals(property, PROPERTY_SCRIPT)) { - bar_item_set_script(bar_item, string_copy(message)); + bar_item_set_script(bar_item, token_to_string(get_token(&message))); } else if (token_equals(property, PROPERTY_CLICK_SCRIPT)) { - bar_item_set_click_script(bar_item, string_copy(message)); + bar_item_set_click_script(bar_item, token_to_string(get_token(&message))); } else if (token_equals(property, PROPERTY_UPDATE_FREQ)) { bar_item->update_frequency = token_to_uint32t(get_token(&message)); } else if (token_equals(property, PROPERTY_POSITION)) { @@ -617,6 +617,9 @@ void handle_message(int sockfd, char* message) { char* rbr_msg = get_batch_line(&message); handle_domain_rename(rsp, command, rbr_msg); free(rbr_msg); + } else if (token_equals(command, DOMAIN_EXIT)) { + bar_manager_destroy(&g_bar_manager); + exit(0); } else { char* rbr_msg = get_batch_line(&message); fprintf(rsp, "unknown domain %s\n", command.text); diff --git a/src/message.h b/src/message.h index 7159d7a..02647d7 100644 --- a/src/message.h +++ b/src/message.h @@ -27,6 +27,8 @@ #define DOMAIN_SET "--set" +#define DOMAIN_EXIT "--exit" + #define SUB_DOMAIN_ICON "icon" #define SUB_DOMAIN_LABEL "label" #define SUB_DOMAIN_BACKGROUND "background" diff --git a/src/misc/helpers.h b/src/misc/helpers.h index b34353d..e1cc712 100644 --- a/src/misc/helpers.h +++ b/src/misc/helpers.h @@ -261,7 +261,8 @@ static inline char* read_file(char* path) { int len = lseek(fd, 0, SEEK_END); char* file = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - return file; + free(path); + return string_copy(file); } static inline char* resolve_path(char* path) { @@ -269,6 +270,7 @@ static inline char* resolve_path(char* path) { char* home = getenv("HOME"); char buf[256]; snprintf(buf, sizeof(buf), "%s%s", home, &path[1]); + free(path); return string_copy(buf); } return path; diff --git a/src/text.c b/src/text.c index 7d473e1..55a6173 100644 --- a/src/text.c +++ b/src/text.c @@ -74,7 +74,7 @@ bool text_set_string(struct text* text, char* string, bool forced) { return false; } if (text->line.line) text_destroy_line(text); - if (string != text->string && !text->string) free(text->string); + if (string != text->string && text->string) free(text->string); text->string = string; text_prepare_line(text); return true; @@ -88,6 +88,7 @@ bool text_set_color(struct text* text, uint32_t color) { bool text_set_font(struct text* text, char* font_string, bool forced) { if (!font_string) return false; if (!forced && text->font_name && strcmp(text->font_name, font_string) == 0) { free(font_string); return false; } + if (font_string != text->font_name && text->font_name) free(text->font_name); if (text->font) CFRelease(text->font); text->font = text_create_font(font_string);