From a31e3c4c76a2246fd04bfa485242535ee299e09c Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 30 Sep 2022 18:37:51 +0300 Subject: [PATCH 1/3] Improve whitespace handlilng in FFF --- lib/flipper_format/flipper_format_stream.c | 67 ++++++++++++++-------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index e4b7b3003..5b872c818 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -4,6 +4,10 @@ #include "flipper_format_stream.h" #include "flipper_format_stream_i.h" +static inline bool flipper_format_stream_is_space(char c) { + return c == ' ' || c == '\t' || c == flipper_format_eolr; +} + static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) { size_t bytes_written = stream_write(stream, data, data_size); return bytes_written == data_size; @@ -118,55 +122,68 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str } static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) { - string_reset(value); + enum { + LeadingSpace, + ReadValue, + TrailingSpace + } state = LeadingSpace; const size_t buffer_size = 32; uint8_t buffer[buffer_size]; bool result = false; bool error = false; + string_reset(value); + while(true) { size_t was_read = stream_read(stream, buffer, buffer_size); if(was_read == 0) { - // check EOF - if(stream_eof(stream) && string_size(value) > 0) { + if(state != LeadingSpace && stream_eof(stream)) { result = true; *last = true; - break; + } else { + error = true; } } for(uint16_t i = 0; i < was_read; i++) { - uint8_t data = buffer[i]; - if(data == flipper_format_eoln) { - if(string_size(value) > 0) { - if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { - error = true; - break; - } + const uint8_t data = buffer[i]; - result = true; - *last = true; + if(state == LeadingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(data == flipper_format_eoln) { + stream_seek(stream, i - was_read, StreamOffsetFromCurrent); + error = true; break; } else { - error = true; + state = ReadValue; + string_push_back(value, data); } - } else if(data == ' ') { - if(string_size(value) > 0) { + } else if(state == ReadValue) { + if(flipper_format_stream_is_space(data)) { + state = TrailingSpace; + } else if(data == flipper_format_eoln) { if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { error = true; - break; + } else { + result = true; + *last = true; } - - result = true; - *last = false; break; + } else { + string_push_back(value, data); } - - } else if(data == flipper_format_eolr) { - // Ignore - } else { - string_push_back(value, data); + } else if(state == TrailingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { + error = true; + } else { + *last = (data == flipper_format_eoln); + result = true; + } + break; } } From 7a75df83b4eaf9cd6bc3c45794e4dcab35a8a561 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 30 Sep 2022 19:11:07 +0300 Subject: [PATCH 2/3] Add tests for odd fff user input --- .../flipper_format/flipper_format_test.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 86e2df21e..60376ec8f 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -57,6 +57,16 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n" "Hex data: DE AD BE"; #define READ_TEST_FLP "ff_flp.test" +#define READ_TEST_ODD "ff_oddities.test" +static const char* test_data_odd = "Filetype: Flipper File test\n" + "Version: 666\t\t\n" // Tabs before newline + "# This is comment\n" + "String data: String\r\n" // Windows newline in a UNIX file + "Int32 data: 1234 -6345 7813 0 \n" // Trailing whitespace + "Uint32 data: 1234 0 5678 9098 7654321 \n" // Extra whitespace + "Float data: 1.5\t \t1000.0\n" // Mixed whitespace + "Bool data:\t\ttrue false\n" // Leading tabs after key + "Hex data: DE AD BE\t "; // Mixed trailing whitespace // data created by user on linux machine static const char* test_file_linux = TEST_DIR READ_TEST_NIX; @@ -64,6 +74,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX; static const char* test_file_windows = TEST_DIR READ_TEST_WIN; // data created by flipper itself static const char* test_file_flipper = TEST_DIR READ_TEST_FLP; +// data containing odd user input +static const char* test_file_oddities = TEST_DIR READ_TEST_ODD; static bool storage_write_string(const char* path, const char* data) { Storage* storage = furi_record_open(RECORD_STORAGE); @@ -503,6 +515,11 @@ MU_TEST(flipper_format_multikey_test) { mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error"); } +MU_TEST(flipper_format_oddities_test) { + mu_assert(storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); + mu_assert(test_read(test_file_linux), "Read test error [Oddities]"); +} + MU_TEST_SUITE(flipper_format) { tests_setup(); MU_RUN_TEST(flipper_format_write_test); @@ -516,6 +533,7 @@ MU_TEST_SUITE(flipper_format) { MU_RUN_TEST(flipper_format_update_2_test); MU_RUN_TEST(flipper_format_update_2_result_test); MU_RUN_TEST(flipper_format_multikey_test); + MU_RUN_TEST(flipper_format_oddities_test); tests_teardown(); } From 601e8cbd485857d28bb77ade5735d34c8df3e80e Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 30 Sep 2022 19:26:09 +0300 Subject: [PATCH 3/3] Adjust formatting --- .../flipper_format/flipper_format_test.c | 24 ++++++++++++------- lib/flipper_format/flipper_format_stream.c | 6 +---- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 60376ec8f..15dba6996 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -59,14 +59,21 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n" #define READ_TEST_FLP "ff_flp.test" #define READ_TEST_ODD "ff_oddities.test" static const char* test_data_odd = "Filetype: Flipper File test\n" - "Version: 666\t\t\n" // Tabs before newline + // Tabs before newline + "Version: 666\t\t\n" "# This is comment\n" - "String data: String\r\n" // Windows newline in a UNIX file - "Int32 data: 1234 -6345 7813 0 \n" // Trailing whitespace - "Uint32 data: 1234 0 5678 9098 7654321 \n" // Extra whitespace - "Float data: 1.5\t \t1000.0\n" // Mixed whitespace - "Bool data:\t\ttrue false\n" // Leading tabs after key - "Hex data: DE AD BE\t "; // Mixed trailing whitespace + // Windows newline in a UNIX file + "String data: String\r\n" + // Trailing whitespace + "Int32 data: 1234 -6345 7813 0 \n" + // Extra whitespace + "Uint32 data: 1234 0 5678 9098 7654321 \n" + // Mixed whitespace + "Float data: 1.5\t \t1000.0\n" + // Leading tabs after key + "Bool data:\t\ttrue false\n" + // Mixed trailing whitespace + "Hex data: DE AD BE\t "; // data created by user on linux machine static const char* test_file_linux = TEST_DIR READ_TEST_NIX; @@ -516,7 +523,8 @@ MU_TEST(flipper_format_multikey_test) { } MU_TEST(flipper_format_oddities_test) { - mu_assert(storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); + mu_assert( + storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); mu_assert(test_read(test_file_linux), "Read test error [Oddities]"); } diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index 5b872c818..4ed41fea4 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -122,11 +122,7 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str } static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) { - enum { - LeadingSpace, - ReadValue, - TrailingSpace - } state = LeadingSpace; + enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace; const size_t buffer_size = 32; uint8_t buffer[buffer_size]; bool result = false;