From 1b141ac7549e5e5fd9ece66934915aedfd248abf Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 27 Mar 2022 17:22:18 -0500 Subject: [PATCH] Bugfix: Partial string functions are incorrect. The tests exposed these problems. The *_assure() functions are operating as if they are *_assure_nulless(). Remove the NULL checks that should not be there and fix the documentation comments. The *_assure() functions are not considering the following: 1) The case where range.stop is >= source.used. 2) The fact that range.stop is inclusive and should not be directly used in the same way that *.used is used. In the case of (1), if the stop range result in it overflowing past the actual length, the previous code results in invalid reads. In the case of (2), the stop.range needs to instead be stop.range + 1. --- level_0/f_string/c/string/dynamic.c | 58 ++++--------------------------------- level_0/f_string/c/string/dynamic.h | 6 ---- 2 files changed, 6 insertions(+), 58 deletions(-) diff --git a/level_0/f_string/c/string/dynamic.c b/level_0/f_string/c/string/dynamic.c index ed363a6..b22cf30 100644 --- a/level_0/f_string/c/string/dynamic.c +++ b/level_0/f_string/c/string/dynamic.c @@ -45,18 +45,6 @@ extern "C" { while (i <= source.used && j <= destination->used) { - if (!source.string[source.used - i]) { - ++i; - - continue; - } - - if (!destination->string[destination->used - j]) { - ++j; - - continue; - } - if (source.string[source.used - i] != destination->string[destination->used - j]) { return private_f_string_append(source.string, source.used, destination); } @@ -292,24 +280,13 @@ extern "C" { return private_f_string_append(source.string + range.start, length, destination); } + const f_array_length_t stop = range.stop >= source.used ? source.used : range.stop + 1; f_array_length_t i = 1; f_array_length_t j = 1; while (i <= length && j <= destination->used) { - if (!source.string[range.stop - i]) { - ++i; - - continue; - } - - if (!destination->string[destination->used - j]) { - ++j; - - continue; - } - - if (source.string[range.stop - i] != destination->string[destination->used - j]) { + if (source.string[stop - i] != destination->string[destination->used - j]) { return private_f_string_append(source.string + range.start, length, destination); } @@ -337,12 +314,13 @@ extern "C" { return private_f_string_append_nulless(source.string + range.start, length, destination); } + const f_array_length_t stop = range.stop >= source.used ? source.used : range.stop + 1; f_array_length_t i = 1; f_array_length_t j = 1; while (i <= length && j <= destination->used) { - if (!source.string[range.stop - i]) { + if (!source.string[stop - i]) { ++i; continue; @@ -354,7 +332,7 @@ extern "C" { continue; } - if (source.string[range.stop - i] != destination->string[destination->used - j]) { + if (source.string[stop - i] != destination->string[destination->used - j]) { return private_f_string_append_nulless(source.string + range.start, length, destination); } @@ -431,7 +409,7 @@ extern "C" { #endif // _di_f_string_dynamic_partial_mash_nulless_ #ifndef _di_f_string_dynamic_partial_mish_ - f_status_t f_string_partial_dynamic_mish(const f_string_static_t glue, const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t * const destination) { + f_status_t f_string_dynamic_partial_mish(const f_string_static_t glue, const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t * const destination) { #ifndef _di_level_0_parameter_checking_ if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ @@ -515,18 +493,6 @@ extern "C" { while (i < length && j < destination->used) { - if (!source.string[i + range.start]) { - ++i; - - continue; - } - - if (!destination->string[j]) { - ++j; - - continue; - } - if (source.string[i + range.start] != destination->string[j]) { return private_f_string_prepend(source.string + range.start, length, destination); } @@ -627,18 +593,6 @@ extern "C" { while (i < source.used && j < destination->used) { - if (!source.string[i]) { - ++i; - - continue; - } - - if (!destination->string[j]) { - ++j; - - continue; - } - if (source.string[i] != destination->string[j]) { return private_f_string_prepend(source.string, source.used, destination); } diff --git a/level_0/f_string/c/string/dynamic.h b/level_0/f_string/c/string/dynamic.h index be5e8aa..21a9c17 100644 --- a/level_0/f_string/c/string/dynamic.h +++ b/level_0/f_string/c/string/dynamic.h @@ -449,8 +449,6 @@ extern "C" { /** * Append the source string onto the destination only if the string is not already at the end and restricted to the given range. * - * This ignores NULL characters when comparing both the source and the destination. - * * @param source * The source string to append. * @param range @@ -681,8 +679,6 @@ extern "C" { * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. * - * This ignores NULL characters when comparing both the source and the destination. - * * @param source * The source string to prepend. * @param range @@ -789,8 +785,6 @@ extern "C" { * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. * - * This ignores NULL characters when comparing both the source and the destination. - * * @param source * The source string to prepend. * @param destination -- 1.8.3.1