From: Kevin Day Date: Sat, 10 Dec 2022 16:28:24 +0000 (-0600) Subject: Security: Invalid write in FSS functions and ensure a reset used length on error. X-Git-Tag: 0.6.2~25 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=0b365fd6548b2453a408b6c4798bfab94227590d;p=fll Security: Invalid write in FSS functions and ensure a reset used length on error. The command that triggers this is "fss_basic_write -oc hi there". An invalid write is happening due to not always performing the array size increase operations. Update all FSS write functions with more thorough checks. This problem is being obfuscated by the lossy allocation. When errors happen the destination->used needs to be consistently reset to the original value on return. Use the lossy allocation as well for allocation shwere the increase by is a raw digit. In these specific cases use state.step_small rather than state.step_large. Rename used_start to destination_used for improved consistency. --- diff --git a/level_1/fl_fss/c/fss/basic.c b/level_1/fl_fss/c/fss/basic.c index 610848e..e82e410 100644 --- a/level_1/fl_fss/c/fss/basic.c +++ b/level_1/fl_fss/c/fss/basic.c @@ -88,10 +88,6 @@ extern "C" { return F_data_not_eos; } - // Ensure that there is room for the potential terminating newline. - status = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status)) return status; - const f_array_length_t destination_used = destination->used; for (; range->start <= range->stop && range->start < content.used; ++range->start) { @@ -110,10 +106,26 @@ extern "C" { if (content.string[range->start] == f_fss_delimit_placeholder_s.string[0]) continue; + status = f_string_dynamic_increase(state.step_large, destination); + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + destination->string[destination->used++] = content.string[range->start]; } // for if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { + status = f_string_dynamic_increase(state.step_large, destination); + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + destination->string[destination->used++] = f_fss_basic_close_s.string[0]; } @@ -154,15 +166,23 @@ extern "C" { f_status_t status = private_fl_fss_basic_write(F_true, object, quote ? quote : f_fss_delimit_quote_double_s.string[0], state, range, destination); + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + if (status == F_data_not_stop || status == F_data_not_eos) { - // Objects cannot be empty, so write a quoted empty string. - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); + // Objects cannot be empty, so write a quote empty string. + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); - if (F_status_is_error(status_allocation)) { - destination->used = destination_used; + if (F_status_is_error(status_allocation)) { + destination->used = destination_used; - return status_allocation; + return status_allocation; + } } destination->string[destination->used++] = quote ? f_fss_delimit_quote_single_s.string[0] : f_fss_delimit_quote_double_s.string[0]; diff --git a/level_1/fl_fss/c/fss/basic_list.c b/level_1/fl_fss/c/fss/basic_list.c index ff31dd3..f19a48d 100644 --- a/level_1/fl_fss/c/fss/basic_list.c +++ b/level_1/fl_fss/c/fss/basic_list.c @@ -313,10 +313,10 @@ extern "C" { } // Ensure that there is room for a slash delimit and possibly the end of content character. - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) return status; - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; bool is_comment = F_false; bool has_graph = F_false; @@ -359,15 +359,23 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { - status = F_status_set_error(F_interrupt); + destination->used = destination_used; - break; + return F_status_set_error(F_interrupt); } } if (content.string[range->start] == f_fss_delimit_placeholder_s.string[0]) continue; if (content.string[range->start] != f_fss_delimit_slash_s.string[0]) break; + status = f_string_dynamic_increase(state.step_large, destination); + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; ++slash_count; } // for @@ -426,7 +434,7 @@ extern "C" { if (content.string[range->start] == f_fss_eol_s.string[0] || range->start >= content.used || range->start > range->stop) { // Increase by slash and basic list open and possible newline. - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; @@ -493,14 +501,19 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { status = f_string_dynamic_increase(state.step_large, destination); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } // Check to see if a newline exists, at the end. if (destination->used) { @@ -785,8 +798,10 @@ extern "C" { if (status == F_none_stop || status == F_none_eos) { if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; + } destination->string[destination->used++] = f_fss_basic_list_open_s.string[0]; @@ -800,11 +815,7 @@ extern "C" { return F_data_not_eos; } - // Ensure that there is room for a slash delimit, the object open character, and the end of line character. - status = f_string_dynamic_increase_by(4, destination); - if (F_status_is_error(status)) return status; - - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; f_array_length_t i = 0; f_array_length_t slash_count = 0; @@ -874,7 +885,7 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } @@ -952,26 +963,26 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { if (complete == f_fss_complete_full_trim_e) { - status = private_fl_fss_basic_list_write_object_trim(used_start, state, destination); + status = private_fl_fss_basic_list_write_object_trim(destination_used, state, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } } - status = f_string_dynamic_increase_by(2, destination); + status = f_string_dynamic_increase(state.step_small + 2, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } diff --git a/level_1/fl_fss/c/fss/embedded_list.c b/level_1/fl_fss/c/fss/embedded_list.c index ba0230b..cc568b2 100644 --- a/level_1/fl_fss/c/fss/embedded_list.c +++ b/level_1/fl_fss/c/fss/embedded_list.c @@ -688,7 +688,7 @@ extern "C" { if (range->start > range->stop || range->start >= content.used) { if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status_allocation)) return status_allocation; destination->string[destination->used++] = f_fss_embedded_list_close_s.string[0]; @@ -698,11 +698,7 @@ extern "C" { return status; } - // Ensure that there is room for a slash delimit and possibly the end of content characters. - status = f_string_dynamic_increase_by(4, destination); - if (F_status_is_error(status)) return status; - - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; bool is_comment = F_false; bool ends_on_eol = F_false; @@ -739,6 +735,9 @@ extern "C" { do_prepend = F_false; } + status = f_string_dynamic_increase(state.step_large, destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = content.string[range->start]; for (++range->start; range->start <= range->stop && range->start < content.used; ++range->start) { @@ -747,15 +746,23 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { - status = F_status_set_error(F_interrupt); + destination->used = destination_used; - break; + return F_status_set_error(F_interrupt); } } if (content.string[range->start] == f_fss_delimit_placeholder_s.string[0]) continue; if (content.string[range->start] != f_fss_delimit_slash_s.string[0]) break; + status = f_string_dynamic_increase(state.step_large, destination); + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; ++slash_count; } // for @@ -794,7 +801,7 @@ extern "C" { } // Increase by character at "start" and possible newline. - status = f_string_dynamic_increase_by(2, destination); + status = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = content.string[start]; @@ -855,7 +862,7 @@ extern "C" { } // Increase by slash and extended list open and possible newline. - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; @@ -922,13 +929,13 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) return status; if (!ends_on_eol) { @@ -1248,8 +1255,10 @@ extern "C" { if (status == F_data_not_stop || status == F_data_not_eos) { if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; + } destination->string[destination->used++] = f_fss_embedded_list_open_s.string[0]; @@ -1262,10 +1271,10 @@ extern "C" { } // Ensure that there is room for a slash delimit, the object open character, and the end of line character. - status = f_string_dynamic_increase_by(4, destination); + status = f_string_dynamic_increase_by(state.step_small + 4, destination); if (F_status_is_error(status)) return status; - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; f_array_length_t i = 0; f_array_length_t slash_count = 0; @@ -1337,7 +1346,7 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } @@ -1363,9 +1372,9 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { - status = F_status_set_error(F_interrupt); + destination->used = destination_used; - break; + return F_status_set_error(F_interrupt); } } @@ -1375,8 +1384,6 @@ extern "C" { ++slash_count; } // for - if (F_status_is_error(status)) break; - if (range->start > range->stop || range->start >= object.used) { // Slashes at the end of the object must be delimited to avoid delimiting the object close character. @@ -1430,17 +1437,17 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { if (complete == f_fss_complete_full_trim_e) { - status = private_fl_fss_basic_list_write_object_trim(used_start, state, destination); + status = private_fl_fss_basic_list_write_object_trim(destination_used, state, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } @@ -1449,10 +1456,10 @@ extern "C" { ends_on_space = F_true; } - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } diff --git a/level_1/fl_fss/c/fss/extended.c b/level_1/fl_fss/c/fss/extended.c index bc1d8c7..56d5a17 100644 --- a/level_1/fl_fss/c/fss/extended.c +++ b/level_1/fl_fss/c/fss/extended.c @@ -132,14 +132,24 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ + const f_array_length_t destination_used = destination->used; + // This operates exactly like an object, syntax-wise. const f_status_t status = private_fl_fss_basic_write(F_false, content, quote ? quote : f_fss_delimit_quote_double_s.string[0], state, range, destination); + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + if (status == F_data_not_stop || status == F_data_not_eos) { // Content that is empty must be represented by a quote empty string. - const f_status_t status_allocation = f_string_dynamic_increase_by(4, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 4, destination); + if (F_status_is_error(status_allocation)) return status_allocation; + } destination->string[destination->used++] = quote ? f_fss_delimit_quote_single_s.string[0] : f_fss_delimit_quote_double_s.string[0]; destination->string[destination->used++] = quote ? f_fss_delimit_quote_single_s.string[0] : f_fss_delimit_quote_double_s.string[0]; @@ -158,17 +168,18 @@ extern "C" { return F_none_eos; } - if (F_status_is_error_not(status)) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); + // Ensure that there is room, including the slash delimit and possibly the end of content characters. + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status_allocation)) return status_allocation; + } - if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_next_e) { - destination->string[destination->used++] = f_fss_extended_next_s.string[0]; - } + if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_next_e) { + destination->string[destination->used++] = f_fss_extended_next_s.string[0]; + } - if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { - destination->string[destination->used++] = f_fss_extended_close_s.string[0]; - } + if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { + destination->string[destination->used++] = f_fss_extended_close_s.string[0]; } return status; @@ -202,15 +213,28 @@ f_status_t fl_fss_extended_object_write(const f_string_static_t object, const f_ if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; f_status_t status = private_fl_fss_basic_write(F_true, object, quote ? quote : f_fss_delimit_quote_double_s.string[0], state, range, destination); + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + if (status == F_data_not_stop || status == F_data_not_eos) { // Objects cannot be empty, so write a quote empty string. - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); + + if (F_status_is_error(status_allocation)) { + destination->used = destination_used; + + return status_allocation; + } + } destination->string[destination->used++] = quote ? f_fss_delimit_quote_single_s.string[0] : f_fss_delimit_quote_double_s.string[0]; destination->string[destination->used++] = quote ? f_fss_delimit_quote_single_s.string[0] : f_fss_delimit_quote_double_s.string[0]; @@ -221,12 +245,22 @@ f_status_t fl_fss_extended_object_write(const f_string_static_t object, const f_ f_status_t status2 = F_none; if (complete == f_fss_complete_full_trim_e) { - status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double_s.string[0], used_start, state, destination); - if (F_status_is_error(status2)) return status2; + status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double_s.string[0], destination_used, state, destination); + + if (F_status_is_error(status2)) { + destination->used = destination_used; + + return status2; + } } status2 = f_string_dynamic_increase(state.step_large, destination); - if (F_status_is_error(status2)) return status2; + + if (F_status_is_error(status2)) { + destination->used = destination_used; + + return status2; + } destination->string[destination->used++] = f_fss_extended_open_s.string[0]; } diff --git a/level_1/fl_fss/c/fss/extended_list.c b/level_1/fl_fss/c/fss/extended_list.c index 9e30b75..8f2bfd5 100644 --- a/level_1/fl_fss/c/fss/extended_list.c +++ b/level_1/fl_fss/c/fss/extended_list.c @@ -241,8 +241,10 @@ extern "C" { if (range->start > range->stop || range->start >= content.used) { if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; + } destination->string[destination->used++] = f_fss_extended_list_close_s.string[0]; destination->string[destination->used++] = f_fss_extended_list_close_end_s.string[0]; @@ -252,10 +254,10 @@ extern "C" { } // Ensure that there is room for a slash delimit and possibly the end of content characters. - status = f_string_dynamic_increase_by(4, destination); + status = f_string_dynamic_increase_by(state.step_small + 4, destination); if (F_status_is_error(status)) return status; - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; bool is_comment = F_false; bool ends_on_eol = F_false; @@ -263,11 +265,10 @@ extern "C" { bool do_prepend = prepend ? F_true : F_false; f_array_length_t i = 0; + f_array_length_t r = 0; f_array_length_t slash_count = 0; f_array_length_t start = 0; - f_array_length_t r = 0; - uint8_t width = 0; while (range->start <= range->stop && range->start < content.used) { @@ -286,11 +287,18 @@ extern "C" { slash_count = 1; if (do_prepend) { + status = f_string_dynamic_increase_by(state.step_small + prepend->used, destination); + if (F_status_is_error(status)) break; + status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(status)) break; do_prepend = F_false; } + else { + status = f_string_dynamic_increase(state.step_large, destination); + if (F_status_is_error(status)) break; + } destination->string[destination->used++] = content.string[range->start]; @@ -300,15 +308,23 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { - status = F_status_set_error(F_interrupt); + destination->used = destination_used; - break; + return F_status_set_error(F_interrupt); } } if (content.string[range->start] == f_fss_delimit_placeholder_s.string[0]) continue; if (content.string[range->start] != f_fss_delimit_slash_s.string[0]) break; + status = f_string_dynamic_increase(state.step_large, destination); + + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } + destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; ++slash_count; } // for @@ -323,9 +339,7 @@ extern "C" { // Do nothing. } else if (content.string[range->start] == f_fss_eol_s.string[0] || range->start >= content.used || range->start > range->stop) { - - // increase by total slashes + 1 and extended list close. - status = f_string_dynamic_increase_by(2, destination); + status = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; @@ -344,7 +358,7 @@ extern "C" { } // Increase by character at "start" and possible newline. - status = f_string_dynamic_increase_by(2, destination); + status = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = content.string[start]; @@ -405,7 +419,7 @@ extern "C" { } // Increase by slash and extended list close. - status = f_string_dynamic_increase_by(2, destination); + status = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; @@ -472,14 +486,18 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e || complete == f_fss_complete_end_e) { - status = f_string_dynamic_increase_by(3, destination); - if (F_status_is_error(status)) return status; + status = f_string_dynamic_increase_by(state.step_small + 3, destination); + if (F_status_is_error(status)) { + destination->used = destination_used; + + return status; + } if (!ends_on_eol) { destination->string[destination->used++] = f_fss_eol_s.string[0]; @@ -798,8 +816,10 @@ extern "C" { if (status == F_data_not_stop || status == F_data_not_eos) { if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { - const f_status_t status_allocation = f_string_dynamic_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + { + const f_status_t status_allocation = f_string_dynamic_increase_by(state.step_small + 2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; + } destination->string[destination->used++] = f_fss_extended_list_open_s.string[0]; @@ -812,10 +832,10 @@ extern "C" { } // Ensure that there is room for a slash delimit, the object open character, and the end of line character. - status = f_string_dynamic_increase_by(4, destination); + status = f_string_dynamic_increase_by(state.step_small + 4, destination); if (F_status_is_error(status)) return status; - const f_array_length_t used_start = destination->used; + const f_array_length_t destination_used = destination->used; f_array_length_t i = 0; f_array_length_t slash_count = 0; @@ -887,7 +907,7 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } @@ -913,9 +933,9 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { - status = F_status_set_error(F_interrupt); + destination->used = destination_used; - break; + return F_status_set_error(F_interrupt); } } @@ -925,8 +945,6 @@ extern "C" { ++slash_count; } // for - if (F_status_is_error(status)) break; - if (range->start > range->stop || range->start >= object.used) { // Slashes at the end of the object must be delimited to avoid delimiting the object close character. @@ -980,17 +998,17 @@ extern "C" { } // while if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } if (complete == f_fss_complete_partial_e || complete == f_fss_complete_partial_trim_e || complete == f_fss_complete_full_e || complete == f_fss_complete_full_trim_e) { if (complete == f_fss_complete_full_trim_e) { - status = private_fl_fss_basic_list_write_object_trim(used_start, state, destination); + status = private_fl_fss_basic_list_write_object_trim(destination_used, state, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } @@ -999,10 +1017,10 @@ extern "C" { ends_on_space = F_true; } - status = f_string_dynamic_increase_by(3, destination); + status = f_string_dynamic_increase_by(state.step_small + 3, destination); if (F_status_is_error(status)) { - destination->used = used_start; + destination->used = destination_used; return status; } diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 25ae621..c25535f 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -706,7 +706,7 @@ extern "C" { if (status == F_data_not) return status; // Ensure that there is room for the potential start and stop quotes, a potential delimit at start, and the potential object open character. - status = f_string_dynamic_increase_by(5, destination); + status = f_string_dynamic_increase_by(state.step_small + 5, destination); if (F_status_is_error(status)) return status; const f_array_length_t input_start = range->start; @@ -813,7 +813,7 @@ extern "C" { item_first = range->start++; status = f_fss_skip_past_delimit(state, object, range); - if (F_status_is_error(status)) return status; + if (F_status_is_error(status)) break; if (range->start > range->stop || range->start >= object.used) { @@ -842,20 +842,14 @@ extern "C" { quote_is = F_true; - status = f_string_dynamic_increase_by(item_total, destination); + status = f_string_dynamic_increase_by(item_total + 1, destination); if (F_status_is_error(status)) break; // Add the slashes that delimit the slashes. if (item_first == input_start) { - status = f_string_dynamic_increase(state.step_large, destination); - if (F_status_is_error(status)) break; - destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; } else { - status = f_string_dynamic_increase_by(item_total, destination); - if (F_status_is_error(status)) break; - for (i = 0; i < item_total; ++i) { destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; } // for @@ -921,9 +915,6 @@ extern "C" { destination->string[destination->used++] = f_fss_delimit_slash_s.string[0]; } // for - status = f_string_dynamic_increase_by(width, destination); - if (F_status_is_error(status)) break; - for (i = 0; i < width; ++i) { destination->string[destination->used++] = object.string[range->start + i]; } // for @@ -986,7 +977,7 @@ extern "C" { width = macro_f_utf_byte_width(object.string[range->start]); - status = f_string_dynamic_increase_by(1 + width, destination); + status = f_string_dynamic_increase_by(width + 1, destination); if (F_status_is_error(status)) break; destination->string[destination->used++] = quote_char; @@ -1031,7 +1022,7 @@ extern "C" { } if (quote_is) { - status = f_string_dynamic_increase(state.step_large, destination); + status = f_string_dynamic_increase_by(state.step_small + 2, destination); if (F_status_is_error(status)) { destination->used = used_start; @@ -1051,6 +1042,8 @@ extern "C" { status = state.interrupt((void *) &state, 0); if (F_status_set_fine(status) == F_interrupt) { + destination->used = used_start; + return F_status_set_error(F_interrupt); } } @@ -1089,9 +1082,7 @@ extern "C" { destination->string[used_start] = f_fss_delimit_slash_s.string[0]; } - if (range->start > range->stop) { - return F_none_stop; - } + if (range->start > range->stop) return F_none_stop; return F_none_eos; }