From 9b2f81b860ff583ad9d46686778b9439e2ceecba Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 25 Feb 2022 22:58:24 -0600 Subject: [PATCH] Bugfix: private_fl_print_convert_number() problems and do some cleanup. The private_fl_print_convert_number() function stops either on non-diit, asterisk, or NULL. The code is subtracting 1 from the string position. This allows for the subsequent continue and resulting string increment to not overflow the buffer. The problem happens when the stop position is a non-digit. This non-digit is effectivly being skipped by this logic. Change the logic to always return a position that will allow the subsequent increment without modification. The position at function exit must never be pointing at NULL. The position at function exit must never be pointing at a non-digit. Use "++string" instead of "string += 1". Change the structure to order from 8, 16, 32, 64, and 128. --- level_1/fl_print/c/private-print.c | 57 +++++++++++++++++++++----------------- level_1/fl_print/c/private-print.h | 2 +- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/level_1/fl_print/c/private-print.c b/level_1/fl_print/c/private-print.c index 0d60d2c..d5b50da 100644 --- a/level_1/fl_print/c/private-print.c +++ b/level_1/fl_print/c/private-print.c @@ -26,7 +26,7 @@ extern "C" { unsigned int width = 1; unsigned int precision = 1; - for (; *string; string += 1) { + for (; *string; ++string) { if (*string < 0x2c) { if (*string == f_string_ascii_space_s.string[0]) { @@ -111,8 +111,6 @@ extern "C" { string = private_fl_print_convert_number(string, ap, &precision, status); if (F_status_is_error(*status)) return string; - --string; - flag |= F_print_format_flag_precision_d; } @@ -136,8 +134,6 @@ extern "C" { string = private_fl_print_convert_number(string, ap, &width, status); if (F_status_is_error(*status)) return string; - --string; - continue; } else { @@ -982,8 +978,18 @@ extern "C" { conversion_data.width = precision; } - if (type == f_print_format_type_signed_number_e) { - *status = f_conversion_number_signed_print(va_arg(*ap, f_number_signed_t), conversion_data, stream); + if (type == f_print_format_type_signed_8_e) { + const int8_t value = (int8_t) va_arg(*ap, int); + + *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); + } + else if (type == f_print_format_type_signed_16_e) { + const int16_t value = (int16_t) va_arg(*ap, int); + + *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); + } + else if (type == f_print_format_type_signed_32_e) { + *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, int32_t), conversion_data, stream); } else if (type == f_print_format_type_signed_64_e) { *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, int64_t), conversion_data, stream); @@ -991,34 +997,24 @@ extern "C" { else if (type == f_print_format_type_signed_128_e) { *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, f_int_128_t), conversion_data, stream); } - else if (type == f_print_format_type_signed_32_e) { - *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, int32_t), conversion_data, stream); - } - else if (type == f_print_format_type_signed_16_e) { - const int16_t value = (int16_t) va_arg(*ap, int); - - *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); - } - else if (type == f_print_format_type_signed_8_e) { - const int8_t value = (int8_t) va_arg(*ap, int); - - *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); + else if (type == f_print_format_type_signed_number_e) { + *status = f_conversion_number_signed_print(va_arg(*ap, f_number_signed_t), conversion_data, stream); } else if (type == f_print_format_type_size_e) { *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, size_t), conversion_data, stream); } - else if (type == f_print_format_type_unsigned_32_e) { - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, uint32_t), conversion_data, stream); + else if (type == f_print_format_type_unsigned_8_e) { + const uint8_t value = (uint8_t) va_arg(*ap, unsigned); + + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); } else if (type == f_print_format_type_unsigned_16_e) { const uint16_t value = (uint16_t) va_arg(*ap, unsigned); *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); } - else if (type == f_print_format_type_unsigned_8_e) { - const uint8_t value = (uint8_t) va_arg(*ap, unsigned); - - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); + else if (type == f_print_format_type_unsigned_32_e) { + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, uint32_t), conversion_data, stream); } else if (type == f_print_format_type_unsigned_64_e) { *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, uint64_t), conversion_data, stream); @@ -1137,7 +1133,7 @@ extern "C" { #if !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) f_string_t private_fl_print_convert_number(f_string_t string, va_list *ap, unsigned int * const number, f_status_t * const status) { - for (*number = 0; *string; string += 1) { + for (*number = 0; *string; ++string) { if (*string > 0x2f && *string < 0x3a) { *number *= 10; @@ -1149,10 +1145,19 @@ extern "C" { break; } else { + + // Do not leave string on the non-digit and non-asterisk character. + --string; + break; } } // for + // Do not leave string on the terminating NULL. + if (!string) { + --string; + } + return string; } #endif // !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) diff --git a/level_1/fl_print/c/private-print.h b/level_1/fl_print/c/private-print.h index 5d05be2..551b42e 100644 --- a/level_1/fl_print/c/private-print.h +++ b/level_1/fl_print/c/private-print.h @@ -80,7 +80,7 @@ extern "C" { * * This should be called to convert numbers after a '%', such as the field with or precision. * - * On return the current will point to either the last consecutive character representing a number, the asterisk, or NULL. + * On return the string will point to either the last consecutive character representing a number or the asterisk. * * @param string * The current character position within the string. -- 1.8.3.1