From: Kevin Day Date: Sun, 16 Jan 2022 20:30:13 +0000 (-0600) Subject: Bugfix: Fix problems exposed by unit testing. X-Git-Tag: 0.5.8~112 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=12633225d05eb81a82fa60476aeb3c515d66ed4c;p=fll Bugfix: Fix problems exposed by unit testing. The default f_color_format_t_initialize should still be provided. Remove redundant context->set.warning assignments. Change the logic to not require format strings to be defined thereby avoiding potential segfaults. Avoid using strnlen() and instead use memcpy(). More memory is used when specifying the sizes, but strnlen() calls probably does this to some extent. Doing this reduces the number of calls to copying ranges of strings. Update comments to reflect latest practices. --- diff --git a/level_0/f_color/c/color-common.h b/level_0/f_color/c/color-common.h index efd11b6..c5e20bb 100644 --- a/level_0/f_color/c/color-common.h +++ b/level_0/f_color/c/color-common.h @@ -154,6 +154,7 @@ extern "C" { const char *medium; } f_color_format_t; + #define f_color_format_t_initialize { 0, 0, 0 } #define f_color_format_t_initialize_linux { f_color_string_begin_s, f_color_string_end_s, f_color_string_medium_s } #define f_color_format_t_initialize_xterminal { f_color_string_begin_s, f_color_string_end_s, f_color_string_medium_s } diff --git a/level_0/f_color/c/color.c b/level_0/f_color/c/color.c index 8212ef1..89f6edc 100644 --- a/level_0/f_color/c/color.c +++ b/level_0/f_color/c/color.c @@ -10,9 +10,7 @@ extern "C" { if (!context) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - f_status_t status = F_none; - - // switch to the appropriate terminal color mode + // Switch to the appropriate terminal color mode. { char *environment = getenv("TERM"); @@ -24,7 +22,7 @@ extern "C" { } } - status = macro_fl_color_save_1(&context->reset, context->format, context->list.reset); + f_status_t status = macro_fl_color_save_1(&context->reset, context->format, context->list.reset); if (F_status_is_error_not(status)) { status = macro_fl_color_save_1(&context->warning, context->format, context->list.yellow); @@ -105,9 +103,6 @@ extern "C" { context->set.normal.before = &context->normal; context->set.normal.after = &context->reset; - context->set.warning.before = &context->warning; - context->set.warning.after = &context->reset; - context->set.normal_reset.before = &context->normal_reset; context->set.normal_reset.after = &context->reset; } @@ -117,82 +112,220 @@ extern "C" { #endif // _di_f_color_load_context_ #ifndef _di_f_color_save_ - f_status_t f_color_save(f_string_dynamic_t *buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5) { + f_status_t f_color_save(f_string_dynamic_t * const buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5) { #ifndef _di_level_0_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!color1) return F_status_set_error(F_parameter); - // make sure all data is in the proper order. - if (!color2 && (color3 != 0 || color4 != 0 || color5 != 0)) return F_status_set_error(F_parameter); - if (!color3 && (color4 != 0 || color5 != 0)) return F_status_set_error(F_parameter); - if (!color4 && color5 != 0) return F_status_set_error(F_parameter); + // Require all data to be in the proper order. + if (!color2 && (color3 || color4 || color5)) return F_status_set_error(F_parameter); + if (!color3 && (color4 || color5)) return F_status_set_error(F_parameter); + if (!color4 && color5) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - f_array_length_t string_size = strnlen(format.begin, F_color_max_size_d) + strnlen(format.end, F_color_max_size_d) + 1; + f_array_length_t size_string = 0; + uint8_t size_begin = 0; + uint8_t size_medium = 0; + uint8_t size_end = 0; + uint8_t size_color1 = 0; + uint8_t size_color2 = 0; + uint8_t size_color3 = 0; + uint8_t size_color4 = 0; + uint8_t size_color5 = 0; + + if (format.begin) { + size_begin = strnlen(format.begin, F_color_max_size_d); + size_string += size_begin; + } - if (!color2) string_size += strnlen(color1, F_color_max_size_d); - else if (!color3) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d); - else if (!color4) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d); - else if (!color5) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d) + strnlen(color4, F_color_max_size_d); - else string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d) + strnlen(color4, F_color_max_size_d) + strnlen(color5, F_color_max_size_d); + if (format.medium) { + size_medium += strnlen(format.medium, F_color_max_size_d); + } - if (buffer->size - buffer->used - 1 < string_size) { - f_status_t status = F_none; + if (format.end) { + size_end = strnlen(format.end, F_color_max_size_d); + size_string += size_end; + } - macro_f_string_dynamic_t_resize(status, (*buffer), buffer->used + string_size + 1); + size_color1 = strnlen(color1, F_color_max_size_d); + size_string += size_color1; - if (F_status_is_error(status)) { - return status; - } + if (color2) { + size_color2 = strnlen(color2, F_color_max_size_d); + size_string += size_color2; + } + + if (color3) { + size_color3 = strnlen(color3, F_color_max_size_d); + size_string += size_color3; + } + + if (color4) { + size_color4 = strnlen(color4, F_color_max_size_d); + size_string += size_color4; + } + + if (color5) { + size_color5 = strnlen(color5, F_color_max_size_d); + size_string += size_color5; + } + + { + const f_status_t status = f_string_dynamic_increase_by(size_string + 1, buffer); + if (F_status_is_error(status)) return status; } if (!color2) { - strncat(buffer->string, format.begin, F_color_max_size_d); - strncat(buffer->string, color1, F_color_max_size_d); - strncat(buffer->string, format.end, F_color_max_size_d); + if (size_begin) { + memcpy(buffer->string + buffer->used, format.begin, size_begin); + buffer->used += size_begin; + } + + memcpy(buffer->string + buffer->used, color1, size_color1); + buffer->used += size_color1; + + if (size_end) { + memcpy(buffer->string + buffer->used, format.end, size_end); + buffer->used += size_end; + } } else if (!color3) { - strncat(buffer->string, format.begin, F_color_max_size_d); - strncat(buffer->string, color1, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color2, F_color_max_size_d); - strncat(buffer->string, format.end, F_color_max_size_d); + if (size_begin) { + memcpy(buffer->string + buffer->used, format.begin, size_begin); + buffer->used += size_begin; + } + + memcpy(buffer->string + buffer->used, color1, size_color1); + buffer->used += size_color1; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color2, size_color2); + buffer->used += size_color2; + + if (size_end) { + memcpy(buffer->string + buffer->used, format.end, size_end); + buffer->used += size_end; + } } else if (!color4) { - strncat(buffer->string, format.begin, F_color_max_size_d); - strncat(buffer->string, color1, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color2, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color3, F_color_max_size_d); - strncat(buffer->string, format.end, F_color_max_size_d); + if (size_begin) { + memcpy(buffer->string + buffer->used, format.begin, size_begin); + buffer->used += size_begin; + } + + memcpy(buffer->string + buffer->used, color1, size_color1); + buffer->used += size_color1; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color2, size_color2); + buffer->used += size_color2; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color3, size_color3); + buffer->used += size_color3; + + if (size_end) { + memcpy(buffer->string + buffer->used, format.end, size_end); + buffer->used += size_end; + } } else if (!color5) { - strncat(buffer->string, format.begin, F_color_max_size_d); - strncat(buffer->string, color1, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color2, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color3, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color4, F_color_max_size_d); - strncat(buffer->string, format.end, F_color_max_size_d); + if (size_begin) { + memcpy(buffer->string + buffer->used, format.begin, size_begin); + buffer->used += size_begin; + } + + memcpy(buffer->string + buffer->used, color1, size_color1); + buffer->used += size_color1; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color2, size_color2); + buffer->used += size_color2; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color3, size_color3); + buffer->used += size_color3; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color4, size_color4); + buffer->used += size_color4; + + if (size_end) { + memcpy(buffer->string + buffer->used, format.end, size_end); + buffer->used += size_end; + } } else { - strncat(buffer->string, format.begin, F_color_max_size_d); - strncat(buffer->string, color1, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color2, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color3, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color4, F_color_max_size_d); - strncat(buffer->string, format.medium, F_color_max_size_d); - strncat(buffer->string, color5, F_color_max_size_d); - strncat(buffer->string, format.end, F_color_max_size_d); - } - - buffer->used += string_size; + if (size_begin) { + memcpy(buffer->string + buffer->used, format.begin, size_begin); + buffer->used += size_begin; + } + + memcpy(buffer->string + buffer->used, color1, size_color1); + buffer->used += size_color1; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color2, size_color2); + buffer->used += size_color2; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color3, size_color3); + buffer->used += size_color3; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color4, size_color4); + buffer->used += size_color4; + + if (size_medium) { + memcpy(buffer->string + buffer->used, format.medium, size_medium); + buffer->used += size_medium; + } + + memcpy(buffer->string + buffer->used, color5, size_color5); + buffer->used += size_color5; + + if (size_end) { + memcpy(buffer->string + buffer->used, format.end, size_end); + buffer->used += size_end; + } + } + buffer->string[buffer->used] = 0; return F_none; diff --git a/level_0/f_color/c/color.h b/level_0/f_color/c/color.h index 78b510e..658bcef 100644 --- a/level_0/f_color/c/color.h +++ b/level_0/f_color/c/color.h @@ -48,8 +48,11 @@ extern "C" { * @return * F_none on success. * - * F_memory_not (with error bit) on out of memory. * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_color_save() + * + * @see f_color_save() */ #ifndef _di_f_color_load_context_ extern f_status_t f_color_load_context(f_color_context_t *context, const bool use_light_colors); @@ -66,6 +69,7 @@ extern "C" { * * @param buffer * The string to save the colors to. + * The buffer will become NULL terminated after the appended string length. * @param format * The color format parts. * @param color1 @@ -82,11 +86,14 @@ extern "C" { * @return * F_none on success. * - * F_memory_not (with error bit) on out of memory. * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_string_dynamic_increase_by() + * + * @see f_string_dynamic_increase_by() */ #ifndef _di_f_color_save_ - extern f_status_t f_color_save(f_string_dynamic_t *buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5); + extern f_status_t f_color_save(f_string_dynamic_t * const buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5); #define macro_fl_color_save_1(buffer, format, color1) f_color_save(buffer, format, color1, 0, 0, 0, 0); #define macro_fl_color_save_2(buffer, format, color1, color2) f_color_save(buffer, format, color1, color2, 0, 0, 0);