From c94420cdfac3cf5f4631a5eb63ca33360b719db4 Mon Sep 17 00:00:00 2001 From: Claudius 'keldu' Holeksa Date: Fri, 16 Aug 2024 14:36:48 +0200 Subject: Didn't consider the empty array case in decoding --- modules/codec-json/c++/json.tmpl.hpp | 14 ++++-- modules/codec-json/tests/codec-json.cpp | 85 +++++++++++++++++++++++++++++++++ modules/codec/c++/data.hpp | 1 - 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/modules/codec-json/c++/json.tmpl.hpp b/modules/codec-json/c++/json.tmpl.hpp index c2e5575..d17c02d 100644 --- a/modules/codec-json/c++/json.tmpl.hpp +++ b/modules/codec-json/c++/json.tmpl.hpp @@ -3,8 +3,6 @@ #include #include -#include - namespace saw { namespace impl { struct json_helper { @@ -739,7 +737,6 @@ struct json_decode...>, ToDecode> { std::array found_fields; std::fill(found_fields.begin(), found_fields.end(), false); - std::cout<(); } @@ -835,6 +832,7 @@ struct json_decode, ToDecode> { static error_or decode_flat_level(buffer_view& buff, std::vector>& to, std::array& index, std::array& dims, bool log_dim){ if constexpr (Level == D) { json_helper::skip_whitespace(buff); + try { to.push_back({}); }catch(std::exception& e){ @@ -852,9 +850,17 @@ struct json_decode, ToDecode> { if ( buff.read_composite_length() == 0 ){ return make_error(); } + /** + * Check if array is empty. + */ + bool is_empty = false; + if(buff.read() == ']'){ + buff.read_advance(1); + is_empty = true; + } index[Level] = 0; - for(;;){ + for(;!is_empty;){ // We should have an element right now auto eov = decode_flat_level(buff,to,index,dims, index[Level] == 0 && log_dim); if(eov.is_error()){ diff --git a/modules/codec-json/tests/codec-json.cpp b/modules/codec-json/tests/codec-json.cpp index dd8df8a..3c97935 100644 --- a/modules/codec-json/tests/codec-json.cpp +++ b/modules/codec-json/tests/codec-json.cpp @@ -24,6 +24,12 @@ using TestStruct = Struct< Member, Member >; + +using TestArrayStruct = Array; + +using TestStructArrayStruct = Struct< + Member +>; } SAW_TEST("UInt8 write"){ @@ -317,6 +323,85 @@ SAW_TEST("Struct read and write"){ SAW_EXPECT(native.get<"bar">() == "baz", "Invalid value for bar"); } +SAW_TEST("Array Struct Empty read and write"){ + using namespace saw; + data native{0u}; + data json; + + codec json_codec; + + error_or eov = json_codec.encode(native, json); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + std::string_view str_v = "[]"; + std::string enc_val = convert_to_string(json.get_buffer()); + + SAW_EXPECT(enc_val == str_v, std::string{"Struct not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); + + native = {}; + eov = json_codec.decode(json, native); + SAW_EXPECT(eov.is_value(), "Decoding error"); +} + +SAW_TEST("Array Struct read and write"){ + using namespace saw; + data native{4u}; + data json; + + native.at(0).get<"foo">().set(5); + native.at(0).get<"bar">().set("baz"); + + native.at(1).get<"foo">().set(6); + native.at(1).get<"bar">().set("baz1"); + + native.at(2).get<"foo">().set(326); + native.at(2).get<"bar">().set("baz12"); + + codec json_codec; + + error_or eov = json_codec.encode(native, json); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + std::string_view str_v = "[{\"foo\":5,\"bar\":\"baz\"},{\"foo\":6,\"bar\":\"baz1\"},{\"foo\":326,\"bar\":\"baz12\"},{\"foo\":0,\"bar\":\"\"}]"; + std::string enc_val = convert_to_string(json.get_buffer()); + + SAW_EXPECT(enc_val == str_v, std::string{"Struct not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); + + native = {}; + eov = json_codec.decode(json, native); + SAW_EXPECT(eov.is_value(), "Decoding error"); +} + +SAW_TEST("Struct Array Struct read and write"){ + using namespace saw; + data native; + native.template get<"banana">() = {4u}; + data json; + + native.template get<"banana">().at(0).get<"foo">().set(5); + native.template get<"banana">().at(0).get<"bar">().set("baz"); + + native.template get<"banana">().at(1).get<"foo">().set(6); + native.template get<"banana">().at(1).get<"bar">().set("baz1"); + + native.template get<"banana">().at(2).get<"foo">().set(326); + native.template get<"banana">().at(2).get<"bar">().set("baz12"); + + codec json_codec; + + error_or eov = json_codec.encode(native, json); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + std::string_view str_v = "{\"banana\":[{\"foo\":5,\"bar\":\"baz\"},{\"foo\":6,\"bar\":\"baz1\"},{\"foo\":326,\"bar\":\"baz12\"},{\"foo\":0,\"bar\":\"\"}]}"; + std::string enc_val = convert_to_string(json.get_buffer()); + + SAW_EXPECT(enc_val == str_v, std::string{"Struct not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); + + native = {}; + eov = json_codec.decode(json, native); + SAW_EXPECT(eov.is_value(), "Decoding error"); +} + SAW_TEST("Int8 read"){ using namespace saw; data native_int; diff --git a/modules/codec/c++/data.hpp b/modules/codec/c++/data.hpp index bd4c15b..371ae71 100644 --- a/modules/codec/c++/data.hpp +++ b/modules/codec/c++/data.hpp @@ -537,7 +537,6 @@ class data, encode::Native, storage::Default> { uint64_t s = 1; for(uint64_t iter = 0; iter < Dim; ++iter){ - assert(dims_.at(iter) > 0); s *= dims_.at(iter); } -- cgit v1.2.3