From cb1ccfb0d9dc08f3a076993672164448f2a213a5 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 5 Mar 2023 22:31:11 -0600 Subject: [PATCH] Bugfix: Fix unterminated quote handling issue addressed by specifications clarification. These commits clarified the specification: - 3abbe4b5c683d247407050eaecaa70a2410c6b46 - 6b1720990df42b0024373776f41037b9331cc3cc. This clarification paved the way for a solution to the bug where lines with unterminated quotes are not getting anything at all. By "favoring the typo", the rest of the line is preserved and is able to be printed. --- level_1/fl_fss/c/fss/basic.c | 7 ++++++- level_1/fl_fss/c/fss/extended.c | 20 +++++++++++++++----- level_1/fl_fss/c/private-fss.c | 13 ++++++++++++- level_1/fl_fss/c/private-fss.h | 1 + 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/level_1/fl_fss/c/fss/basic.c b/level_1/fl_fss/c/fss/basic.c index cdcfd3c..a50962a 100644 --- a/level_1/fl_fss/c/fss/basic.c +++ b/level_1/fl_fss/c/fss/basic.c @@ -163,7 +163,12 @@ extern "C" { private_fl_fss_basic_read(buffer, F_true, range, found, quote, delimits, state); - if (F_status_is_error(state->status) || state->status == F_fss_found_object_not || state->status == F_data_not || state->status == F_data_not_eos || state->status == F_data_not_stop) { + if (state->status == F_status_set_error(F_fss_found_object_content_not)) { + + // The private function sets the error bit on unterminated quoted Object. + state->status = F_fss_found_object_content_not; + } + else if (F_status_is_error(state->status) || state->status == F_fss_found_object_not || state->status == F_data_not || state->status == F_data_not_eos || state->status == F_data_not_stop) { delimits->used = delimits_used; } } diff --git a/level_1/fl_fss/c/fss/extended.c b/level_1/fl_fss/c/fss/extended.c index f19fc6a..9d4924c 100644 --- a/level_1/fl_fss/c/fss/extended.c +++ b/level_1/fl_fss/c/fss/extended.c @@ -55,11 +55,16 @@ extern "C" { private_fl_fss_basic_read(buffer, F_false, range, &content_partial, "e, delimits, state); - if (state->status == F_fss_found_object || state->status == F_fss_found_object_content_not) { - state->status = f_string_ranges_increase(state->step_small, found); + if (state->status == F_fss_found_object || F_status_set_fine(state->status) == F_fss_found_object_content_not) { + status = f_string_ranges_increase(state->step_small, found); - if (F_status_is_error_not(state->status) && quotes) { - state->status = f_uint8s_increase(state->step_small, quotes); + if (F_status_is_error_not(status) && quotes) { + status = f_uint8s_increase(state->step_small, quotes); + } + + // The private function sets the error bit on unterminated quoted Object. + if (state->status == F_status_set_error(F_fss_found_object_content_not)) { + state->status = F_fss_found_object_content_not; } if (F_status_is_error(status)) { @@ -228,7 +233,12 @@ extern "C" { private_fl_fss_basic_read(buffer, F_true, range, found, quote, delimits, state); - if (F_status_is_error(state->status) || state->status == F_fss_found_object_not || state->status == F_data_not || state->status == F_data_not_eos || state->status == F_data_not_stop) { + if (state->status == F_status_set_error(F_fss_found_object_content_not)) { + + // The private function sets the error bit on unterminated quoted Object. + state->status = F_fss_found_object_content_not; + } + else if (F_status_is_error(state->status) || state->status == F_fss_found_object_not || state->status == F_data_not || state->status == F_data_not_eos || state->status == F_data_not_stop) { delimits->used = delimits_used; } diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 64e9ba1..b0955cd 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -138,6 +138,9 @@ extern "C" { return; } + // Save the delimits used position in case of unterminated quote. + const f_array_length_t delimits_used = delimits->used; + // Begin the search. found->start = range->start; @@ -625,9 +628,17 @@ extern "C" { } else if (buffer.string[range->start] == f_fss_eol_s.string[0]) { + // The quote is incomplete, so treat the entire line as the Object as per the specification (including the quotes). + // The error bit is set to designate that the Object is found in an erroneous state (not having a terminating quote). + found->start -= 1; + found->stop = range->start - 1; + state->status = F_status_set_error(F_fss_found_object_content_not); + + // The delimits cannot be preserved in this case as per specification. + delimits->used = delimits_used; + // Move the start position to after the EOL. ++range->start; - state->status = F_fss_found_object_not; return; } diff --git a/level_1/fl_fss/c/private-fss.h b/level_1/fl_fss/c/private-fss.h index 30e51f5..3991e28 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -128,6 +128,7 @@ extern "C" { * F_end_not_group_eos if EOS was reached before the a group termination was reached. * F_end_not_group_stop if stop point was reached before the a group termination was reached. * + * F_fss_found_object_content_not (with error bit) If an unterminated quoted Object is found. * F_interrupt (with error bit) if stopping due to an interrupt. * F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard. * F_parameter (with error bit) if a parameter is invalid. -- 1.8.3.1