Fix some pesky leaks, now close to leak free.

Co-authored-by: LeonHeidelbach <leon.heidelbach@hhu.de>
This commit is contained in:
Felix Kratz 2021-12-25 20:45:06 +01:00
parent 3f1ac04a98
commit 3e5c15a9a3
12 changed files with 83 additions and 27 deletions

View file

@ -25,8 +25,16 @@ uninstall: clean
profile: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -g -Ofast -fvisibility=hidden profile: BUILD_FLAGS=-std=c99 -Wall -DDEBUG -g -Ofast -fvisibility=hidden
profile: clean $(x86_BINS) 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) debug: clean $(ARM_BINS)
./bin/sketchybar_arm
update: clean $(UNIVERSAL_BINS) update: clean $(UNIVERSAL_BINS)
rm /usr/local/bin/sketchybar rm /usr/local/bin/sketchybar

View file

@ -181,6 +181,13 @@ void alias_draw(struct alias* alias, CGContextRef context) {
CGContextDrawImage(context, alias->bounds, alias->image_ref); 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) { void alias_calculate_bounds(struct alias* alias, uint32_t x, uint32_t y) {
alias->bounds.origin.x = x; alias->bounds.origin.x = x;
alias->bounds.origin.y = y - alias->bounds.size.height / 2; alias->bounds.origin.y = y - alias->bounds.size.height / 2;

View file

@ -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_calculate_bounds(struct alias* alias, uint32_t x, uint32_t y);
void alias_draw(struct alias* alias, CGContextRef context); void alias_draw(struct alias* alias, CGContextRef context);
void alias_destroy(struct alias* alias);
#endif #endif

View file

@ -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)); bar_item_set_click_script(bar_item, string_copy(ancestor->click_script));
if (bar_item->type == BAR_COMPONENT_SPACE) { 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("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"))); 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); popup_init(&bar_item->popup);
if (default_item) bar_item_inherit_from_item(bar_item, default_item); 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) { 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) { void bar_item_set_name(struct bar_item* bar_item, char* name) {
if (!name) return; if (!name) return;
if (bar_item->name && strcmp(bar_item->name, name) == 0) { free(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; bar_item->name = name;
env_vars_set(&bar_item->signal_args.env_vars, string_copy("NAME"), string_copy(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->update_mask |= UPDATE_SPACE_CHANGE;
bar_item->updates = false; 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("SID"), string_copy("0"));
env_vars_set(&bar_item->signal_args.env_vars, string_copy("DID"), 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) { void bar_item_set_script(struct bar_item* bar_item, char* script) {
if (!script) return; if (!script) return;
if (bar_item->script && strcmp(bar_item->script, script) == 0) { free(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 (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)); char* path = resolve_path(script);
else bar_item->script = 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) { void bar_item_set_click_script(struct bar_item* bar_item, char* script) {
if (!script) return; if (!script) return;
if (bar_item->click_script && strcmp(bar_item->click_script, script) == 0) { free(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 (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)); char* path = resolve_path(script);
else bar_item->click_script = 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) { 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) { void bar_item_destroy(struct bar_item* bar_item) {
if (bar_item->name) free(bar_item->name); if (bar_item->name) free(bar_item->name);
if (bar_item->script && !bar_item->cache_scripts) free(bar_item->script); if (bar_item->script) free(bar_item->script);
if (bar_item->click_script && !bar_item->cache_scripts) free(bar_item->click_script); if (bar_item->click_script) free(bar_item->click_script);
text_destroy(&bar_item->icon); text_destroy(&bar_item->icon);
text_destroy(&bar_item->label); text_destroy(&bar_item->label);
@ -385,6 +391,9 @@ void bar_item_destroy(struct bar_item* bar_item) {
if (bar_item->has_graph) { if (bar_item->has_graph) {
graph_destroy(&bar_item->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); 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); else if (bar_item->group) group_remove_member(bar_item->group, bar_item);
env_vars_destroy(&bar_item->signal_args.env_vars); env_vars_destroy(&bar_item->signal_args.env_vars);

View file

@ -281,14 +281,6 @@ struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager) {
return bar_item; 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) { void bar_manager_update_alias_components(struct bar_manager* bar_manager, bool forced) {
for (int i = 0; i < bar_manager->bar_item_count; i++) { 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; 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); 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) { void bar_manager_serialize(struct bar_manager* bar_manager, FILE* rsp) {
fprintf(rsp, "{\n" fprintf(rsp, "{\n"
"\t\"geometry\": {\n" "\t\"geometry\": {\n"

View file

@ -20,9 +20,9 @@ struct bar_manager {
uint32_t window_level; uint32_t window_level;
CFRunLoopTimerRef refresh_timer; CFRunLoopTimerRef refresh_timer;
CFRunLoopTimerRef shell_refresh_timer; CFRunLoopTimerRef shell_refresh_timer;
struct bar **bars; struct bar** bars;
int bar_count; int bar_count;
struct bar_item **bar_items; struct bar_item** bar_items;
struct bar_item default_item; struct bar_item default_item;
int bar_item_count; int bar_item_count;
char position; 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_display_change(struct bar_manager* bar_manager);
void bar_manager_handle_system_woke(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_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); struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager, CGPoint point, uint32_t sid);

View file

@ -7,6 +7,12 @@ void custom_event_init(struct custom_event* custom_event, char* name, char* noti
custom_event->notification = notification; 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) { void custom_events_init(struct custom_events* custom_events) {
custom_events->count = 0; 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) { 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->count++;
custom_events->events = (struct custom_event**) realloc(custom_events->events, sizeof(struct custom_event*) * 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(); 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; 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) { void custom_events_serialize(struct custom_events* custom_events, FILE* rsp) {
fprintf(rsp, "{\n"); fprintf(rsp, "{\n");
for (int i = 0; i < custom_events->count; i++) { for (int i = 0; i < custom_events->count; i++) {

View file

@ -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); 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); 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); 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); void custom_events_serialize(struct custom_events* custom_events, FILE* rsp);
#endif #endif

View file

@ -240,9 +240,9 @@ static void message_parse_set_message_for_bar_item(FILE* rsp, struct bar_item* b
} }
needs_update = true; needs_update = true;
} else if (token_equals(property, PROPERTY_SCRIPT)) { } 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)) { } 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)) { } else if (token_equals(property, PROPERTY_UPDATE_FREQ)) {
bar_item->update_frequency = token_to_uint32t(get_token(&message)); bar_item->update_frequency = token_to_uint32t(get_token(&message));
} else if (token_equals(property, PROPERTY_POSITION)) { } 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); char* rbr_msg = get_batch_line(&message);
handle_domain_rename(rsp, command, rbr_msg); handle_domain_rename(rsp, command, rbr_msg);
free(rbr_msg); free(rbr_msg);
} else if (token_equals(command, DOMAIN_EXIT)) {
bar_manager_destroy(&g_bar_manager);
exit(0);
} else { } else {
char* rbr_msg = get_batch_line(&message); char* rbr_msg = get_batch_line(&message);
fprintf(rsp, "unknown domain %s\n", command.text); fprintf(rsp, "unknown domain %s\n", command.text);

View file

@ -27,6 +27,8 @@
#define DOMAIN_SET "--set" #define DOMAIN_SET "--set"
#define DOMAIN_EXIT "--exit"
#define SUB_DOMAIN_ICON "icon" #define SUB_DOMAIN_ICON "icon"
#define SUB_DOMAIN_LABEL "label" #define SUB_DOMAIN_LABEL "label"
#define SUB_DOMAIN_BACKGROUND "background" #define SUB_DOMAIN_BACKGROUND "background"

View file

@ -261,7 +261,8 @@ static inline char* read_file(char* path) {
int len = lseek(fd, 0, SEEK_END); int len = lseek(fd, 0, SEEK_END);
char* file = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0); char* file = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd); close(fd);
return file; free(path);
return string_copy(file);
} }
static inline char* resolve_path(char* path) { static inline char* resolve_path(char* path) {
@ -269,6 +270,7 @@ static inline char* resolve_path(char* path) {
char* home = getenv("HOME"); char* home = getenv("HOME");
char buf[256]; char buf[256];
snprintf(buf, sizeof(buf), "%s%s", home, &path[1]); snprintf(buf, sizeof(buf), "%s%s", home, &path[1]);
free(path);
return string_copy(buf); return string_copy(buf);
} }
return path; return path;

View file

@ -74,7 +74,7 @@ bool text_set_string(struct text* text, char* string, bool forced) {
return false; return false;
} }
if (text->line.line) text_destroy_line(text); 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->string = string;
text_prepare_line(text); text_prepare_line(text);
return true; 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) { bool text_set_font(struct text* text, char* font_string, bool forced) {
if (!font_string) return false; if (!font_string) return false;
if (!forced && text->font_name && strcmp(text->font_name, font_string) == 0) { free(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); if (text->font) CFRelease(text->font);
text->font = text_create_font(font_string); text->font = text_create_font(font_string);