From d8e4a73577c21e13268bc0884562a73c6368c578 Mon Sep 17 00:00:00 2001 From: dam Date: Sun, 6 Nov 2022 01:01:20 +0000 Subject: Replaced sprintf with snprintf. --- main.c | 70 ++++++++++++++++++++++++++++++++++++--------------------------- misc.c | 36 ++++++++++++++++++++++++++++++++ readme.md | 2 +- 3 files changed, 77 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index 1dbfbd1..6b4c35a 100644 --- a/main.c +++ b/main.c @@ -156,12 +156,18 @@ char *replace_char(char *string, char find, char replace) { return string; } -char *format_time(char* string, intmax_t time, int length) { - int left_padding = (length - 5) / 2; - int right_padding = length - 5 - left_padding; +// Prints time into string using 5 characters centered according to length. +// The string should have capacity for at least length number of items. +// The terminating null byte ('\0') is included in length. +// TODO Should the null byte be included int he length or not? +char *sprint_time_5cc(char *string, intmax_t time, int length) { + assert(length >= 6); + + int left_padding = (length - 6) / 2; + int right_padding = length - 6 - left_padding; if (time >= (intmax_t)(9999.5 * SECONDS_IN_YEAR)) { - sprintf(string, "%*s ∞ %*s", + snprintf(string, length, "%*s ∞ %*s", left_padding, "", right_padding, ""); } @@ -172,7 +178,7 @@ char *format_time(char* string, intmax_t time, int length) { time >= 9.995 * SECONDS_IN_YEAR ? 1 : 2; - sprintf(string, "%*s%4.*fy%*s", + snprintf(string, length, "%*s%4.*fy%*s", left_padding, "", decimals, value, @@ -185,7 +191,7 @@ char *format_time(char* string, intmax_t time, int length) { time >= 9.995 * SECONDS_IN_DAY ? 1 : 2; - sprintf(string, "%*s%4.*fd%*s", + snprintf(string, length, "%*s%4.*fd%*s", left_padding, "", decimals, value, @@ -194,16 +200,16 @@ char *format_time(char* string, intmax_t time, int length) { else if (time >= SECONDS_IN_MINUTE) { intmax_t hours = (double)time / (double)SECONDS_IN_HOUR; intmax_t minutes = (time - (hours * SECONDS_IN_HOUR) ) / SECONDS_IN_MINUTE; - sprintf(string, "%*s%02jd:%02jd%*s", left_padding, "", hours, minutes, right_padding, ""); + snprintf(string, length, "%*s%02jd:%02jd%*s", left_padding, "", hours, minutes, right_padding, ""); } else if (time > 0) { - sprintf(string, "%*s%3jds %*s", left_padding, "", time, right_padding, ""); + snprintf(string, length, "%*s%3jds %*s", left_padding, "", time, right_padding, ""); } else if (time == 0) { - sprintf(string, "%*s 0 %*s", left_padding, "", right_padding, ""); + snprintf(string, length, "%*s 0 %*s", left_padding, "", right_padding, ""); } else { - sprintf(string, "%*s - %*s", left_padding, "", right_padding, ""); + snprintf(string, length, "%*s - %*s", left_padding, "", right_padding, ""); } return string; } @@ -960,11 +966,10 @@ void draw_tui(database_st *db, layout_st *layout) { attron(COLOR_PAIR(THEME_A) | A_BOLD); } - // Task title. x++; column_width = layout->columns[L_TITLE_IDX].width; - sprintf(string_buffer, "%*s", column_width, ""); + snprintf(string_buffer, string_buffer_size, "%*s", column_width, ""); mvaddnstr(y, x, string_buffer, column_width); mvaddnstr(y, x, task->name, column_width); x += column_width; @@ -979,14 +984,14 @@ void draw_tui(database_st *db, layout_st *layout) { column_width = layout->columns[L_DAYS_IDX + day_idx].width; int64_t task_stime = task->times[day_idx]; total_time = add_int64(total_time, task_stime); - format_time(string_buffer, task_stime, column_width); + sprint_time_5cc(string_buffer, task_stime, column_width + 1); mvaddstr(y, x, string_buffer); x += column_width; } // Task total. x++; - format_time(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width); + sprint_time_5cc(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width + 1); mvaddstr(y, x, string_buffer); // Reset theme. @@ -996,9 +1001,9 @@ void draw_tui(database_st *db, layout_st *layout) { /////////////////////////////////////////////////////////////////////////// // Draw selected/total tasks. - sprintf(string_buffer, " %td/%zd ", db->selected_task+1, db->count); // TODO snprintf() > string_buffer_size => error + snprintf(string_buffer, string_buffer_size, " %td/%zd ", db->selected_task+1, db->count); // TODO snprintf() > string_buffer_size => error if (strlen(string_buffer) > layout->columns[L_TITLE_IDX].width) { - sprintf(string_buffer, "%td", db->selected_task+1); // TODO snprintf() > string_buffer_size => error + snprintf(string_buffer, string_buffer_size, "%td", db->selected_task+1); // TODO snprintf() > string_buffer_size => error } mvaddstr(size_y-1, 1, string_buffer); @@ -1014,7 +1019,7 @@ void draw_tui(database_st *db, layout_st *layout) { column_width = layout->columns[L_DAYS_IDX + idx].width; total_time = add_int64(total_time, daily_total); - format_time(string_buffer, daily_total, column_width); + sprint_time_5cc(string_buffer, daily_total, column_width + 1); // Apply theme. if (idx == now_week_day && active_task != NULL) { @@ -1031,7 +1036,7 @@ void draw_tui(database_st *db, layout_st *layout) { attrset(A_NORMAL); } x++; - format_time(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width); + sprint_time_5cc(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width + 1); mvaddstr(y, x, string_buffer); } @@ -1046,6 +1051,7 @@ void free_memory() { } bool initialize_app_folder() { + size_t temp_size; char* home_path = getenv("HOME"); #if defined(_WIN64) @@ -1054,9 +1060,10 @@ bool initialize_app_folder() { if (home_path != NULL) { - app_folder = malloc(strlen(home_path) + 1 + strlen(APP_FOLDER_NAME) + 1); // Add space for folder separator and NUL. + temp_size = strlen(home_path) + 1 + strlen(APP_FOLDER_NAME) + 1; // Add space for folder separator and '\0'. + app_folder = malloc(temp_size); // TODO Check malloc result. - sprintf(app_folder, "%s/%s", home_path, APP_FOLDER_NAME); + snprintf(app_folder, temp_size, "%s/%s", home_path, APP_FOLDER_NAME); // Create app folder. mkdir(app_folder, 0740); @@ -1066,20 +1073,23 @@ bool initialize_app_folder() { } } else { - app_folder = malloc(3); + temp_size = 3; + app_folder = malloc(temp_size); // TODO Check malloc result. - sprintf(app_folder, "./"); + snprintf(app_folder, temp_size, "./"); } // Set database file path. - db_file_path = malloc(strlen(app_folder) + 1 + strlen(DB_FILE_NAME) + 1); // Add space for folder separator and NUL. + temp_size = strlen(app_folder) + 1 + strlen(DB_FILE_NAME) + 1; // Add space for folder separator and '\0'. + db_file_path = malloc(temp_size); // TODO Check malloc result. - sprintf(db_file_path, "%s/%s", app_folder, DB_FILE_NAME); + snprintf(db_file_path, temp_size, "%s/%s", app_folder, DB_FILE_NAME); // Set archive file path. - ar_file_path = malloc(strlen(app_folder) + 1 + strlen(AR_FILE_NAME) + 1); // Add space for folder separator and NUL. + temp_size = strlen(app_folder) + 1 + strlen(AR_FILE_NAME) + 1; // Add space for folder separator and '\0'. + ar_file_path = malloc(temp_size); // TODO Check malloc result. - sprintf(ar_file_path, "%s/%s", app_folder, AR_FILE_NAME); + snprintf(ar_file_path, temp_size, "%s/%s", app_folder, AR_FILE_NAME); return true; } @@ -1318,7 +1328,7 @@ int main(int argc, char *argv[]) { // Prepare row to input new task name. attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE); - sprintf(string_buffer, "%*s", size_x - 2, ""); + snprintf(string_buffer, string_buffer_size, "%*s", size_x - 2, ""); mvaddstr(selected_task_row, 1, string_buffer); // Get new task name. @@ -1398,7 +1408,7 @@ int main(int argc, char *argv[]) { { attron(A_UNDERLINE); - sprintf(string_buffer, "%*s", input_width, ""); + snprintf(string_buffer, string_buffer_size, "%*s", input_width, ""); mvaddstr(selected_task_row, input_pos_x, string_buffer); echo(); @@ -1522,7 +1532,7 @@ int main(int argc, char *argv[]) { addch(ACS_CKBOARD); addstr(" Move to: "); int input_pos_x = getcurx(stdscr); - sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, ""); + snprintf(string_buffer, string_buffer_size, "%*s", size_x - input_pos_x - 1, ""); attron(A_UNDERLINE); addstr(string_buffer); @@ -1570,7 +1580,7 @@ int main(int argc, char *argv[]) { // TODO Maybe convert this code block on a function? { int input_pos_x = getcurx(stdscr); - sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, ""); + snprintf(string_buffer, string_buffer_size, "%*s", size_x - input_pos_x - 1, ""); attron(A_UNDERLINE); addstr(string_buffer); diff --git a/misc.c b/misc.c index f5a3ada..35a602c 100644 --- a/misc.c +++ b/misc.c @@ -1,3 +1,39 @@ +/* +// Alternative code to print a task row. + + ////////////////////////------------------ + total_time = 0; + char t0[10], t1[10], t2[10], t3[10], t4[10], t5[10], t6[10], t7[10]; + for (int idx = 0; idx < NUM_WEEK_DAYS; idx++) { + total_time = add_int64(total_time, task->times[idx]); + } + snprintf(string_buffer, size_x - 2 + 1, "%-*.*s %*s %*s %*s %*s %*s %*s %*s %*s", + layout->columns[L_TITLE_IDX].width, + layout->columns[L_TITLE_IDX].width, + task->name, + + layout->columns[1].width, + print_time_5cc(t0, task->times[(0 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[2].width, + print_time_5cc(t1, task->times[(1 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[3].width, + print_time_5cc(t2, task->times[(2 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[4].width, + print_time_5cc(t3, task->times[(3 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[5].width, + print_time_5cc(t4, task->times[(4 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[6].width, + print_time_5cc(t5, task->times[(5 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[7].width, + print_time_5cc(t6, task->times[(6 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS], layout->columns[1].width + 1), + layout->columns[L_TOTAL_IDX].width, + print_time_5cc(t1, total_time, layout->columns[L_TOTAL_IDX].width + 1) + ); + mvaddnstr(y, 1, string_buffer, size_x - 2); + ////////////////////////------------------ + + */ + // Writes only the database core structure and the provided task if not null. // Returns success. diff --git a/readme.md b/readme.md index 9006f17..91752bc 100644 --- a/readme.md +++ b/readme.md @@ -57,10 +57,10 @@ Task Time Tracker - [x] Move `store_database_partial` to misc and save only when leaving or after 15 seconds of inactivity and having dirty flag set. - [x] Register kill signals to exit gracefully. - [x] Check if string_buffer needs to be cleared. We may be leaking info on the string_buffer. +- [x] Replaced `sprintf` by `snprintf`; - [ ] Move database actions into functions: - [ ] select_by_id/delta/task - [ ] set_active(db, task) -- [ ] Check if any `sprintf` needs to be replaced by `snprintf`; - [ ] Make sure that string_buffer bounds are respected; - [ ] REVISE ALL CODE ptrdiff_t/size_t (signed/unsigned)! - [ ] Go over all `TODO` items; -- cgit v1.2.3