array.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2025, Benoit BLANCHON
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. #include "Allocators.hpp"
  7. using namespace ArduinoJson::detail;
  8. TEST_CASE("deserialize JSON array") {
  9. SpyingAllocator spy;
  10. JsonDocument doc(&spy);
  11. SECTION("An empty array") {
  12. DeserializationError err = deserializeJson(doc, "[]");
  13. JsonArray arr = doc.as<JsonArray>();
  14. REQUIRE(err == DeserializationError::Ok);
  15. REQUIRE(0 == arr.size());
  16. }
  17. SECTION("Spaces") {
  18. SECTION("Before the opening bracket") {
  19. DeserializationError err = deserializeJson(doc, " []");
  20. JsonArray arr = doc.as<JsonArray>();
  21. REQUIRE(err == DeserializationError::Ok);
  22. REQUIRE(0 == arr.size());
  23. }
  24. SECTION("Before first value") {
  25. DeserializationError err = deserializeJson(doc, "[ \t\r\n42]");
  26. JsonArray arr = doc.as<JsonArray>();
  27. REQUIRE(err == DeserializationError::Ok);
  28. REQUIRE(1 == arr.size());
  29. REQUIRE(arr[0] == 42);
  30. }
  31. SECTION("After first value") {
  32. DeserializationError err = deserializeJson(doc, "[42 \t\r\n]");
  33. JsonArray arr = doc.as<JsonArray>();
  34. REQUIRE(err == DeserializationError::Ok);
  35. REQUIRE(1 == arr.size());
  36. REQUIRE(arr[0] == 42);
  37. }
  38. }
  39. SECTION("Values types") {
  40. SECTION("On integer") {
  41. DeserializationError err = deserializeJson(doc, "[42]");
  42. JsonArray arr = doc.as<JsonArray>();
  43. REQUIRE(err == DeserializationError::Ok);
  44. REQUIRE(1 == arr.size());
  45. REQUIRE(arr[0] == 42);
  46. }
  47. SECTION("Two integers") {
  48. DeserializationError err = deserializeJson(doc, "[42,84]");
  49. JsonArray arr = doc.as<JsonArray>();
  50. REQUIRE(err == DeserializationError::Ok);
  51. REQUIRE(2 == arr.size());
  52. REQUIRE(arr[0] == 42);
  53. REQUIRE(arr[1] == 84);
  54. }
  55. SECTION("Float") {
  56. DeserializationError err = deserializeJson(doc, "[4.2,1e2]");
  57. JsonArray arr = doc.as<JsonArray>();
  58. REQUIRE(err == DeserializationError::Ok);
  59. REQUIRE(2 == arr.size());
  60. REQUIRE(arr[0].as<float>() == Approx(4.2f));
  61. REQUIRE(arr[1] == 1e2f);
  62. REQUIRE(spy.log() == AllocatorLog{
  63. Allocate(sizeofPool()),
  64. Reallocate(sizeofPool(), sizeofPool(2)),
  65. });
  66. }
  67. SECTION("Double") {
  68. DeserializationError err = deserializeJson(doc, "[4.2123456,-7E89]");
  69. JsonArray arr = doc.as<JsonArray>();
  70. REQUIRE(err == DeserializationError::Ok);
  71. REQUIRE(2 == arr.size());
  72. REQUIRE(arr[0].as<double>() == Approx(4.2123456));
  73. REQUIRE(arr[1] == -7E89);
  74. REQUIRE(spy.log() == AllocatorLog{
  75. Allocate(sizeofPool<VariantData>()),
  76. Allocate(sizeofPool<EightByteValue>()),
  77. Reallocate(sizeofPool<VariantData>(),
  78. sizeofPool<VariantData>(2)),
  79. Reallocate(sizeofPool<EightByteValue>(),
  80. sizeofPool<EightByteValue>(2)),
  81. });
  82. }
  83. SECTION("Unsigned long") {
  84. DeserializationError err = deserializeJson(doc, "[4294967295]");
  85. JsonArray arr = doc.as<JsonArray>();
  86. REQUIRE(err == DeserializationError::Ok);
  87. REQUIRE(1 == arr.size());
  88. REQUIRE(arr[0] == 4294967295UL);
  89. }
  90. SECTION("Boolean") {
  91. DeserializationError err = deserializeJson(doc, "[true,false]");
  92. JsonArray arr = doc.as<JsonArray>();
  93. REQUIRE(err == DeserializationError::Ok);
  94. REQUIRE(2 == arr.size());
  95. REQUIRE(arr[0] == true);
  96. REQUIRE(arr[1] == false);
  97. }
  98. SECTION("Null") {
  99. DeserializationError err = deserializeJson(doc, "[null,null]");
  100. JsonArray arr = doc.as<JsonArray>();
  101. REQUIRE(err == DeserializationError::Ok);
  102. REQUIRE(2 == arr.size());
  103. REQUIRE(arr[0].as<const char*>() == 0);
  104. REQUIRE(arr[1].as<const char*>() == 0);
  105. }
  106. }
  107. SECTION("Quotes") {
  108. SECTION("Double quotes") {
  109. DeserializationError err =
  110. deserializeJson(doc, "[ \"hello\" , \"world\" ]");
  111. JsonArray arr = doc.as<JsonArray>();
  112. REQUIRE(err == DeserializationError::Ok);
  113. REQUIRE(2 == arr.size());
  114. REQUIRE(arr[0] == "hello");
  115. REQUIRE(arr[1] == "world");
  116. }
  117. SECTION("Single quotes") {
  118. DeserializationError err = deserializeJson(doc, "[ 'hello' , 'world' ]");
  119. JsonArray arr = doc.as<JsonArray>();
  120. REQUIRE(err == DeserializationError::Ok);
  121. REQUIRE(2 == arr.size());
  122. REQUIRE(arr[0] == "hello");
  123. REQUIRE(arr[1] == "world");
  124. }
  125. SECTION("No quotes") {
  126. DeserializationError err = deserializeJson(doc, "[ hello , world ]");
  127. REQUIRE(err == DeserializationError::InvalidInput);
  128. }
  129. SECTION("Double quotes (empty strings)") {
  130. DeserializationError err = deserializeJson(doc, "[\"\",\"\"]");
  131. JsonArray arr = doc.as<JsonArray>();
  132. REQUIRE(err == DeserializationError::Ok);
  133. REQUIRE(2 == arr.size());
  134. REQUIRE(arr[0] == "");
  135. REQUIRE(arr[1] == "");
  136. }
  137. SECTION("Single quotes (empty strings)") {
  138. DeserializationError err = deserializeJson(doc, "[\'\',\'\']");
  139. JsonArray arr = doc.as<JsonArray>();
  140. REQUIRE(err == DeserializationError::Ok);
  141. REQUIRE(2 == arr.size());
  142. REQUIRE(arr[0] == "");
  143. REQUIRE(arr[1] == "");
  144. }
  145. SECTION("No quotes (empty strings)") {
  146. DeserializationError err = deserializeJson(doc, "[,]");
  147. REQUIRE(err == DeserializationError::InvalidInput);
  148. }
  149. SECTION("Closing single quotes missing") {
  150. DeserializationError err = deserializeJson(doc, "[\"]");
  151. REQUIRE(err == DeserializationError::IncompleteInput);
  152. }
  153. SECTION("Closing double quotes missing") {
  154. DeserializationError err = deserializeJson(doc, "[\']");
  155. REQUIRE(err == DeserializationError::IncompleteInput);
  156. }
  157. }
  158. SECTION("Premature null-terminator") {
  159. SECTION("After opening bracket") {
  160. DeserializationError err = deserializeJson(doc, "[");
  161. REQUIRE(err == DeserializationError::IncompleteInput);
  162. }
  163. SECTION("After value") {
  164. DeserializationError err = deserializeJson(doc, "[1");
  165. REQUIRE(err == DeserializationError::IncompleteInput);
  166. }
  167. SECTION("After comma") {
  168. DeserializationError err = deserializeJson(doc, "[1,");
  169. REQUIRE(err == DeserializationError::IncompleteInput);
  170. }
  171. }
  172. SECTION("Premature end of input") {
  173. const char* input = "[1,2]";
  174. SECTION("After opening bracket") {
  175. DeserializationError err = deserializeJson(doc, input, 1);
  176. REQUIRE(err == DeserializationError::IncompleteInput);
  177. }
  178. SECTION("After value") {
  179. DeserializationError err = deserializeJson(doc, input, 2);
  180. REQUIRE(err == DeserializationError::IncompleteInput);
  181. }
  182. SECTION("After comma") {
  183. DeserializationError err = deserializeJson(doc, input, 3);
  184. REQUIRE(err == DeserializationError::IncompleteInput);
  185. }
  186. }
  187. SECTION("Misc") {
  188. SECTION("Nested objects") {
  189. char jsonString[] =
  190. " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
  191. DeserializationError err = deserializeJson(doc, jsonString);
  192. JsonArray arr = doc.as<JsonArray>();
  193. JsonObject object1 = arr[0];
  194. const JsonObject object2 = arr[1];
  195. JsonObject object3 = arr[2];
  196. REQUIRE(err == DeserializationError::Ok);
  197. REQUIRE(object1.isNull() == false);
  198. REQUIRE(object2.isNull() == false);
  199. REQUIRE(object3.isNull() == true);
  200. REQUIRE(2 == object1.size());
  201. REQUIRE(2 == object2.size());
  202. REQUIRE(0 == object3.size());
  203. REQUIRE(1 == object1["a"].as<int>());
  204. REQUIRE(2 == object1["b"].as<int>());
  205. REQUIRE(3 == object2["c"].as<int>());
  206. REQUIRE(4 == object2["d"].as<int>());
  207. REQUIRE(0 == object3["e"].as<int>());
  208. }
  209. }
  210. SECTION("Should clear the JsonArray") {
  211. deserializeJson(doc, "[1,2,3,4]");
  212. spy.clearLog();
  213. deserializeJson(doc, "[]");
  214. JsonArray arr = doc.as<JsonArray>();
  215. REQUIRE(arr.size() == 0);
  216. REQUIRE(spy.log() == AllocatorLog{
  217. Deallocate(sizeofArray(4)),
  218. });
  219. }
  220. }
  221. TEST_CASE("deserialize JSON array under memory constraints") {
  222. TimebombAllocator timebomb(100);
  223. SpyingAllocator spy(&timebomb);
  224. JsonDocument doc(&spy);
  225. SECTION("empty array requires no allocation") {
  226. timebomb.setCountdown(0);
  227. char input[] = "[]";
  228. DeserializationError err = deserializeJson(doc, input);
  229. REQUIRE(err == DeserializationError::Ok);
  230. }
  231. SECTION("allocation of pool list fails") {
  232. timebomb.setCountdown(0);
  233. char input[] = "[1]";
  234. DeserializationError err = deserializeJson(doc, input);
  235. REQUIRE(err == DeserializationError::NoMemory);
  236. REQUIRE(doc.as<std::string>() == "[]");
  237. }
  238. SECTION("allocation of pool fails") {
  239. timebomb.setCountdown(0);
  240. char input[] = "[1]";
  241. DeserializationError err = deserializeJson(doc, input);
  242. REQUIRE(err == DeserializationError::NoMemory);
  243. REQUIRE(doc.as<std::string>() == "[]");
  244. }
  245. SECTION("allocation of string fails in array") {
  246. timebomb.setCountdown(1);
  247. char input[] = "[0,\"hi!\"]";
  248. DeserializationError err = deserializeJson(doc, input);
  249. REQUIRE(err == DeserializationError::NoMemory);
  250. REQUIRE(doc.as<std::string>() == "[0,null]");
  251. }
  252. SECTION("don't store space characters") {
  253. deserializeJson(doc, " [ \"1234567\" ] ");
  254. REQUIRE(spy.log() ==
  255. AllocatorLog{
  256. Allocate(sizeofPool()),
  257. Allocate(sizeofStringBuffer()),
  258. Reallocate(sizeofStringBuffer(), sizeofString("1234567")),
  259. Reallocate(sizeofPool(), sizeofArray(1)),
  260. });
  261. }
  262. }