// ArduinoJson - https://arduinojson.org // Copyright © 2014-2024, Benoit BLANCHON // MIT License #include #include #include "Allocators.hpp" template static void checkValue(const char* input, T expected) { JsonDocument doc; DeserializationError error = deserializeMsgPack(doc, input); REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(doc.as() == expected); } static void checkError(size_t timebombCountDown, const char* input, DeserializationError expected) { TimebombAllocator timebomb(timebombCountDown); JsonDocument doc(&timebomb); DeserializationError error = deserializeMsgPack(doc, input); CAPTURE(input); REQUIRE(error == expected); } TEST_CASE("deserialize MsgPack value") { SECTION("nil") { checkValue("\xc0", nullptr); } SECTION("bool") { checkValue("\xc2", false); checkValue("\xc3", true); } SECTION("positive fixint") { checkValue("\x00", 0); checkValue("\x7F", 127); } SECTION("negative fixint") { checkValue("\xe0", -32); checkValue("\xff", -1); } SECTION("uint 8") { checkValue("\xcc\x00", 0); checkValue("\xcc\xff", 255); } SECTION("uint 16") { checkValue("\xcd\x00\x00", 0); checkValue("\xcd\xFF\xFF", 65535); checkValue("\xcd\x30\x39", 12345); } SECTION("uint 32") { checkValue("\xCE\x00\x00\x00\x00", 0x00000000U); checkValue("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); checkValue("\xCE\x12\x34\x56\x78", 0x12345678U); } SECTION("uint 64") { #if ARDUINOJSON_USE_LONG_LONG checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0xFFFFFFFFFFFFFFFFU); checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", 0x123456789ABCDEF0U); #else checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("int 8") { checkValue("\xd0\x00", 0); checkValue("\xd0\xff", -1); } SECTION("int 16") { checkValue("\xD1\x00\x00", 0); checkValue("\xD1\xFF\xFF", -1); checkValue("\xD1\xCF\xC7", -12345); } SECTION("int 32") { checkValue("\xD2\x00\x00\x00\x00", 0); checkValue("\xD2\xFF\xFF\xFF\xFF", -1); checkValue("\xD2\xB6\x69\xFD\x2E", -1234567890); } SECTION("int 64") { #if ARDUINOJSON_USE_LONG_LONG checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", int64_t(0xFFFFFFFFFFFFFFFFU)); checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", int64_t(0x123456789ABCDEF0)); #else checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("float 32") { checkValue("\xCA\x00\x00\x00\x00", 0.0f); checkValue("\xCA\x40\x48\xF5\xC3", 3.14f); } SECTION("float 64") { checkValue("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); checkValue("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); } SECTION("fixstr") { checkValue("\xA0", std::string("")); checkValue("\xABhello world", std::string("hello world")); checkValue("\xBFhello world hello world hello !", std::string("hello world hello world hello !")); } SECTION("str 8") { checkValue("\xd9\x05hello", std::string("hello")); } SECTION("str 16") { checkValue("\xda\x00\x05hello", std::string("hello")); } SECTION("str 32") { checkValue("\xdb\x00\x00\x00\x05hello", std::string("hello")); } } TEST_CASE("deserializeMsgPack() under memory constaints") { SECTION("single values always fit") { checkError(0, "\xc0", DeserializationError::Ok); // nil checkError(0, "\xc2", DeserializationError::Ok); // false checkError(0, "\xc3", DeserializationError::Ok); // true checkError(0, "\xcc\x00", DeserializationError::Ok); // uint 8 checkError(0, "\xcd\x30\x39", DeserializationError::Ok); // uint 16 checkError(0, "\xCE\x12\x34\x56\x78", DeserializationError::Ok); // uint 32 } SECTION("fixstr") { checkError(2, "\xA7ZZZZZZZ", DeserializationError::Ok); checkError(0, "\xA7ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 8") { checkError(2, "\xD9\x07ZZZZZZZ", DeserializationError::Ok); checkError(0, "\xD9\x07ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 16") { checkError(2, "\xDA\x00\x07ZZZZZZZ", DeserializationError::Ok); checkError(0, "\xDA\x00\x07ZZZZZZZ", DeserializationError::NoMemory); } SECTION("str 32") { checkError(2, "\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::Ok); checkError(0, "\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::NoMemory); } SECTION("fixarray") { checkError(0, "\x90", DeserializationError::Ok); // [] checkError(0, "\x91\x01", DeserializationError::NoMemory); // [1] checkError(1, "\x91\x01", DeserializationError::Ok); // [1] } SECTION("array 16") { checkError(0, "\xDC\x00\x00", DeserializationError::Ok); checkError(0, "\xDC\x00\x01\x01", DeserializationError::NoMemory); checkError(1, "\xDC\x00\x01\x01", DeserializationError::Ok); } SECTION("array 32") { checkError(0, "\xDD\x00\x00\x00\x00", DeserializationError::Ok); checkError(0, "\xDD\x00\x00\x00\x01\x01", DeserializationError::NoMemory); checkError(1, "\xDD\x00\x00\x00\x01\x01", DeserializationError::Ok); } SECTION("fixmap") { SECTION("{}") { checkError(0, "\x80", DeserializationError::Ok); } SECTION("{H:1}") { checkError(0, "\x81\xA1H\x01", DeserializationError::NoMemory); checkError(3, "\x81\xA1H\x01", DeserializationError::Ok); } SECTION("{H:1,W:2}") { checkError(3, "\x82\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); checkError(5, "\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok); } } SECTION("map 16") { SECTION("{}") { checkError(0, "\xDE\x00\x00", DeserializationError::Ok); } SECTION("{H:1}") { checkError(2, "\xDE\x00\x01\xA1H\x01", DeserializationError::NoMemory); checkError(3, "\xDE\x00\x01\xA1H\x01", DeserializationError::Ok); } SECTION("{H:1,W:2}") { checkError(3, "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); checkError(5, "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); } } SECTION("map 32") { SECTION("{}") { checkError(0, "\xDF\x00\x00\x00\x00", DeserializationError::Ok); } SECTION("{H:1}") { checkError(2, "\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::NoMemory); checkError(3, "\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok); } SECTION("{H:1,W:2}") { checkError(3, "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); checkError(5, "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); } } }