]> Kevux Git Server - fll/commitdiff
Bugfix: Partial string functions are incorrect.
authorKevin Day <thekevinday@gmail.com>
Sun, 27 Mar 2022 22:22:18 +0000 (17:22 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 27 Mar 2022 22:22:18 +0000 (17:22 -0500)
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
level_0/f_string/c/string/dynamic.h

index ed363a6a81b608f78eb68b02b2ef10ae657f4374..b22cf3047bb36147d7bbd6b79b935a1d8ae460b6 100644 (file)
@@ -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);
       }
index be5e8aa61581afeeb87b0dd31e8e0e40aae97862..21a9c170fbff7a5e1a2857258025dd226dd54411 100644 (file)
@@ -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