From fce926420ea546e25c414c95d7dd55c32c346080 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 27 Jun 2020 18:17:45 -0500 Subject: [PATCH] Bugfix: when --line is used, lengths passed buffer size aren't handled. data->line is not a position, do not use it as a position (if (data->line < data->buffer.used) { is doing this). If the line is exceeds the buffer, return f_data_not and properly handle that return case. For --total, this means print 0. For just about everything else, print nothing. --- level_3/iki_read/c/private-iki_read.c | 48 ++++++++++++++++++++++------------- level_3/iki_read/c/private-iki_read.h | 1 + 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/level_3/iki_read/c/private-iki_read.c b/level_3/iki_read/c/private-iki_read.c index f8c5da2..04ac184 100644 --- a/level_3/iki_read/c/private-iki_read.c +++ b/level_3/iki_read/c/private-iki_read.c @@ -301,26 +301,24 @@ extern "C" { f_return_status iki_read_process_at(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_string_range *range) { if (data->parameters[iki_read_parameter_line].result != f_console_result_additional) return F_false; - if (data->line < data->buffer.used) { - f_string_length line = 0; + f_string_length line = 0; - range->start = 0; - if (data->line > 0) { - for (; line < data->line && range->start < data->buffer.used; range->start++) { - if (data->buffer.string[range->start] == f_string_eol[0]) line++; - } // for - } + range->start = 0; + if (data->line > 0) { + for (; line < data->line && range->start < data->buffer.used; range->start++) { + if (data->buffer.string[range->start] == f_string_eol[0]) line++; + } // for + } - range->stop = range->start; - for (; range->stop < data->buffer.used; range->stop++) { + if (line == data->line) { + for (range->stop = range->start; range->stop < data->buffer.used; range->stop++) { if (data->buffer.string[range->stop] == f_string_eol[0]) break; } // for - } - else { - range->start = data->buffer.used + 1; + + return F_true; } - return F_true; + return F_data_not; } #endif // _di_iki_read_process_at_ @@ -335,11 +333,16 @@ extern "C" { if (data->parameters[iki_read_parameter_whole].result == f_console_result_found) { f_string_range buffer_range = f_macro_string_range_initialize(data->buffer.used); - if (iki_read_process_at(arguments, file_name, data, &buffer_range)) { + status = iki_read_process_at(arguments, file_name, data, &buffer_range); + + if (status == F_true) { if (buffer_range.start > data->buffer.used) { return F_data_not; } } + else if (status == F_data_not) { + return F_data_not; + } if (data->mode == iki_read_mode_content) { status = iki_read_process_buffer_ranges_whole(arguments, file_name, buffer_range, data, &variable, &vocabulary, &content, &content); @@ -357,11 +360,16 @@ extern "C" { else { f_string_range buffer_range = f_macro_string_range_initialize(data->buffer.used); - if (iki_read_process_at(arguments, file_name, data, &buffer_range)) { + status = iki_read_process_at(arguments, file_name, data, &buffer_range); + + if (status == F_true) { if (buffer_range.start > data->buffer.used) { return F_data_not; } } + else if (status == F_data_not) { + return F_data_not; + } if (data->mode == iki_read_mode_content) { status = iki_read_process_buffer_ranges(arguments, file_name, data, &buffer_range, &variable, &vocabulary, &content, &content); @@ -587,12 +595,18 @@ extern "C" { f_status status = F_none; f_string_range range = f_macro_string_range_initialize(data->buffer.used); - if (iki_read_process_at(arguments, file_name, data, &range)) { + status = iki_read_process_at(arguments, file_name, data, &range); + + if (status == F_true) { if (range.start > data->buffer.used) { printf("0\n"); return F_none; } } + else if (status == F_data_not) { + printf("0\n"); + return F_none; + } status = fl_iki_read(&data->buffer, &range, variable, vocabulary, content); if (F_status_is_error(status)) { diff --git a/level_3/iki_read/c/private-iki_read.h b/level_3/iki_read/c/private-iki_read.h index 692427b..437ed93 100644 --- a/level_3/iki_read/c/private-iki_read.h +++ b/level_3/iki_read/c/private-iki_read.h @@ -106,6 +106,7 @@ extern "C" { * @return * F_true is returned if the range is processed. * F_false is returned if the range is not processed. + * F_data_not if the range is processed, but the requested line is out of range. * * Status codes (with error bit) are returned on any problem. */ -- 1.8.3.1