deserializeVariant.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2023, Benoit BLANCHON
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. #include "Allocators.hpp"
  7. using ArduinoJson::detail::sizeofArray;
  8. using ArduinoJson::detail::sizeofObject;
  9. using ArduinoJson::detail::sizeofString;
  10. template <typename T>
  11. static void checkValue(const char* input, T expected) {
  12. JsonDocument doc(4096);
  13. DeserializationError error = deserializeMsgPack(doc, input);
  14. REQUIRE(error == DeserializationError::Ok);
  15. REQUIRE(doc.is<T>());
  16. REQUIRE(doc.as<T>() == expected);
  17. }
  18. static void checkError(size_t capacity, size_t timebombCountDown,
  19. const char* input, DeserializationError expected) {
  20. TimebombAllocator timebombAllocator(timebombCountDown);
  21. JsonDocument doc(capacity, &timebombAllocator);
  22. DeserializationError error = deserializeMsgPack(doc, input);
  23. CAPTURE(input);
  24. REQUIRE(error == expected);
  25. }
  26. TEST_CASE("deserialize MsgPack value") {
  27. SECTION("nil") {
  28. checkValue("\xc0", nullptr);
  29. }
  30. SECTION("bool") {
  31. checkValue<bool>("\xc2", false);
  32. checkValue<bool>("\xc3", true);
  33. }
  34. SECTION("positive fixint") {
  35. checkValue<int>("\x00", 0);
  36. checkValue<int>("\x7F", 127);
  37. }
  38. SECTION("negative fixint") {
  39. checkValue<int>("\xe0", -32);
  40. checkValue<int>("\xff", -1);
  41. }
  42. SECTION("uint 8") {
  43. checkValue<int>("\xcc\x00", 0);
  44. checkValue<int>("\xcc\xff", 255);
  45. }
  46. SECTION("uint 16") {
  47. checkValue<int>("\xcd\x00\x00", 0);
  48. checkValue<int>("\xcd\xFF\xFF", 65535);
  49. checkValue<int>("\xcd\x30\x39", 12345);
  50. }
  51. SECTION("uint 32") {
  52. checkValue<uint32_t>("\xCE\x00\x00\x00\x00", 0x00000000U);
  53. checkValue<uint32_t>("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU);
  54. checkValue<uint32_t>("\xCE\x12\x34\x56\x78", 0x12345678U);
  55. }
  56. SECTION("uint 64") {
  57. #if ARDUINOJSON_USE_LONG_LONG
  58. checkValue<uint64_t>("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
  59. checkValue<uint64_t>("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
  60. 0xFFFFFFFFFFFFFFFFU);
  61. checkValue<uint64_t>("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
  62. 0x123456789ABCDEF0U);
  63. #else
  64. checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", nullptr);
  65. checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr);
  66. checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr);
  67. #endif
  68. }
  69. SECTION("int 8") {
  70. checkValue<int>("\xd0\x00", 0);
  71. checkValue<int>("\xd0\xff", -1);
  72. }
  73. SECTION("int 16") {
  74. checkValue<int>("\xD1\x00\x00", 0);
  75. checkValue<int>("\xD1\xFF\xFF", -1);
  76. checkValue<int>("\xD1\xCF\xC7", -12345);
  77. }
  78. SECTION("int 32") {
  79. checkValue<int>("\xD2\x00\x00\x00\x00", 0);
  80. checkValue<int>("\xD2\xFF\xFF\xFF\xFF", -1);
  81. checkValue<int>("\xD2\xB6\x69\xFD\x2E", -1234567890);
  82. }
  83. SECTION("int 64") {
  84. #if ARDUINOJSON_USE_LONG_LONG
  85. checkValue<int64_t>("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U));
  86. checkValue<int64_t>("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
  87. int64_t(0xFFFFFFFFFFFFFFFFU));
  88. checkValue<int64_t>("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
  89. int64_t(0x123456789ABCDEF0));
  90. #else
  91. checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", nullptr);
  92. checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr);
  93. checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr);
  94. #endif
  95. }
  96. SECTION("float 32") {
  97. checkValue<double>("\xCA\x00\x00\x00\x00", 0.0f);
  98. checkValue<double>("\xCA\x40\x48\xF5\xC3", 3.14f);
  99. }
  100. SECTION("float 64") {
  101. checkValue<double>("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0);
  102. checkValue<double>("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415);
  103. }
  104. SECTION("fixstr") {
  105. checkValue<std::string>("\xA0", std::string(""));
  106. checkValue<std::string>("\xABhello world", std::string("hello world"));
  107. checkValue<std::string>("\xBFhello world hello world hello !",
  108. std::string("hello world hello world hello !"));
  109. }
  110. SECTION("str 8") {
  111. checkValue<std::string>("\xd9\x05hello", std::string("hello"));
  112. }
  113. SECTION("str 16") {
  114. checkValue<std::string>("\xda\x00\x05hello", std::string("hello"));
  115. }
  116. SECTION("str 32") {
  117. checkValue<std::string>("\xdb\x00\x00\x00\x05hello", std::string("hello"));
  118. }
  119. }
  120. TEST_CASE("deserializeMsgPack() under memory constaints") {
  121. SECTION("single values always fit") {
  122. checkError(0, 0, "\xc0", DeserializationError::Ok); // nil
  123. checkError(0, 0, "\xc2", DeserializationError::Ok); // false
  124. checkError(0, 0, "\xc3", DeserializationError::Ok); // true
  125. checkError(0, 0, "\xcc\x00", DeserializationError::Ok); // uint 8
  126. checkError(0, 0, "\xcd\x30\x39", DeserializationError::Ok); // uint 16
  127. checkError(0, 0, "\xCE\x12\x34\x56\x78",
  128. DeserializationError::Ok); // uint 32
  129. }
  130. SECTION("fixstr") {
  131. checkError(0, 2, "\xA7ZZZZZZZ", DeserializationError::Ok);
  132. checkError(0, 0, "\xA7ZZZZZZZ", DeserializationError::NoMemory);
  133. }
  134. SECTION("str 8") {
  135. checkError(0, 2, "\xD9\x07ZZZZZZZ", DeserializationError::Ok);
  136. checkError(0, 0, "\xD9\x07ZZZZZZZ", DeserializationError::NoMemory);
  137. }
  138. SECTION("str 16") {
  139. checkError(0, 2, "\xDA\x00\x07ZZZZZZZ", DeserializationError::Ok);
  140. checkError(0, 0, "\xDA\x00\x07ZZZZZZZ", DeserializationError::NoMemory);
  141. }
  142. SECTION("str 32") {
  143. checkError(0, 2, "\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::Ok);
  144. checkError(0, 0, "\xDB\x00\x00\x00\x07ZZZZZZZ",
  145. DeserializationError::NoMemory);
  146. }
  147. SECTION("fixarray") {
  148. checkError(sizeofArray(0), 1, "\x90", DeserializationError::Ok); // []
  149. checkError(sizeofArray(0), 1, "\x91\x01",
  150. DeserializationError::NoMemory); // [1]
  151. checkError(sizeofArray(1), 1, "\x91\x01",
  152. DeserializationError::Ok); // [1]
  153. checkError(sizeofArray(1), 1, "\x92\x01\x02",
  154. DeserializationError::NoMemory); // [1,2]
  155. }
  156. SECTION("array 16") {
  157. checkError(sizeofArray(0), 1, "\xDC\x00\x00", DeserializationError::Ok);
  158. checkError(sizeofArray(0), 1, "\xDC\x00\x01\x01",
  159. DeserializationError::NoMemory);
  160. checkError(sizeofArray(1), 1, "\xDC\x00\x01\x01", DeserializationError::Ok);
  161. checkError(sizeofArray(1), 1, "\xDC\x00\x02\x01\x02",
  162. DeserializationError::NoMemory);
  163. }
  164. SECTION("array 32") {
  165. checkError(sizeofArray(0), 1, "\xDD\x00\x00\x00\x00",
  166. DeserializationError::Ok);
  167. checkError(sizeofArray(0), 1, "\xDD\x00\x00\x00\x01\x01",
  168. DeserializationError::NoMemory);
  169. checkError(sizeofArray(1), 1, "\xDD\x00\x00\x00\x01\x01",
  170. DeserializationError::Ok);
  171. checkError(sizeofArray(1), 1, "\xDD\x00\x00\x00\x02\x01\x02",
  172. DeserializationError::NoMemory);
  173. }
  174. SECTION("fixmap") {
  175. SECTION("{}") {
  176. checkError(sizeofObject(0), 0, "\x80", DeserializationError::Ok);
  177. }
  178. SECTION("{H:1}") {
  179. checkError(sizeofObject(0), 0, "\x81\xA1H\x01",
  180. DeserializationError::NoMemory);
  181. checkError(sizeofObject(1) + sizeofString(2), 3, "\x81\xA1H\x01",
  182. DeserializationError::Ok);
  183. }
  184. SECTION("{H:1,W:2}") {
  185. checkError(sizeofObject(1) + sizeofString(2), 3, "\x82\xA1H\x01\xA1W\x02",
  186. DeserializationError::NoMemory);
  187. checkError(sizeofObject(2) + 2 * sizeofString(2), 5,
  188. "\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok);
  189. }
  190. }
  191. SECTION("map 16") {
  192. SECTION("{}") {
  193. checkError(sizeofObject(0), 0, "\xDE\x00\x00", DeserializationError::Ok);
  194. }
  195. SECTION("{H:1}") {
  196. checkError(sizeofObject(1) + sizeofString(2), 1, "\xDE\x00\x01\xA1H\x01",
  197. DeserializationError::NoMemory);
  198. checkError(sizeofObject(1) + sizeofString(2), 3, "\xDE\x00\x01\xA1H\x01",
  199. DeserializationError::Ok);
  200. }
  201. SECTION("{H:1,W:2}") {
  202. checkError(sizeofObject(1) + sizeofString(2), 3,
  203. "\xDE\x00\x02\xA1H\x01\xA1W\x02",
  204. DeserializationError::NoMemory);
  205. checkError(sizeofObject(2) + 2 * sizeofObject(1), 5,
  206. "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
  207. }
  208. }
  209. SECTION("map 32") {
  210. SECTION("{}") {
  211. checkError(sizeofObject(0), 0, "\xDF\x00\x00\x00\x00",
  212. DeserializationError::Ok);
  213. }
  214. SECTION("{H:1}") {
  215. checkError(sizeofObject(1) + sizeofString(2), 1,
  216. "\xDF\x00\x00\x00\x01\xA1H\x01",
  217. DeserializationError::NoMemory);
  218. checkError(sizeofObject(1) + sizeofString(2), 3,
  219. "\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok);
  220. }
  221. SECTION("{H:1,W:2}") {
  222. checkError(sizeofObject(1) + 2 * sizeofString(2), 3,
  223. "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
  224. DeserializationError::NoMemory);
  225. checkError(sizeofObject(2) + 2 * sizeofObject(1), 5,
  226. "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
  227. DeserializationError::Ok);
  228. }
  229. }
  230. }