string.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2023, Benoit BLANCHON
  3. // MIT License
  4. #define ARDUINOJSON_DECODE_UNICODE 1
  5. #include <ArduinoJson.h>
  6. #include <catch.hpp>
  7. #include "Allocators.hpp"
  8. using ArduinoJson::detail::sizeofArray;
  9. using ArduinoJson::detail::sizeofObject;
  10. using ArduinoJson::detail::sizeofString;
  11. TEST_CASE("Valid JSON strings value") {
  12. struct TestCase {
  13. const char* input;
  14. const char* expectedOutput;
  15. };
  16. TestCase testCases[] = {
  17. {"\"hello world\"", "hello world"},
  18. {"\'hello world\'", "hello world"},
  19. {"'\"'", "\""},
  20. {"'\\\\'", "\\"},
  21. {"'\\/'", "/"},
  22. {"'\\b'", "\b"},
  23. {"'\\f'", "\f"},
  24. {"'\\n'", "\n"},
  25. {"'\\r'", "\r"},
  26. {"'\\t'", "\t"},
  27. {"\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"", "1\"2\\3/4\b5\f6\n7\r8\t9"},
  28. {"'\\u0041'", "A"},
  29. {"'\\u00e4'", "\xc3\xa4"}, // ä
  30. {"'\\u00E4'", "\xc3\xa4"}, // ä
  31. {"'\\u3042'", "\xe3\x81\x82"}, // あ
  32. {"'\\ud83d\\udda4'", "\xf0\x9f\x96\xa4"}, // 🖤
  33. {"'\\uF053'", "\xef\x81\x93"}, // issue #1173
  34. {"'\\uF015'", "\xef\x80\x95"}, // issue #1173
  35. {"'\\uF054'", "\xef\x81\x94"}, // issue #1173
  36. };
  37. const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
  38. JsonDocument doc;
  39. for (size_t i = 0; i < testCount; i++) {
  40. const TestCase& testCase = testCases[i];
  41. CAPTURE(testCase.input);
  42. DeserializationError err = deserializeJson(doc, testCase.input);
  43. CHECK(err == DeserializationError::Ok);
  44. CHECK(doc.as<std::string>() == testCase.expectedOutput);
  45. }
  46. }
  47. TEST_CASE("\\u0000") {
  48. JsonDocument doc;
  49. DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\"");
  50. REQUIRE(err == DeserializationError::Ok);
  51. const char* result = doc.as<const char*>();
  52. CHECK(result[0] == 'w');
  53. CHECK(result[1] == 'x');
  54. CHECK(result[2] == 0);
  55. CHECK(result[3] == 'y');
  56. CHECK(result[4] == 'z');
  57. CHECK(result[5] == 0);
  58. CHECK(doc.as<JsonString>().size() == 5);
  59. CHECK(doc.as<std::string>().size() == 5);
  60. }
  61. TEST_CASE("Truncated JSON string") {
  62. const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"};
  63. const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
  64. JsonDocument doc;
  65. for (size_t i = 0; i < testCount; i++) {
  66. const char* input = testCases[i];
  67. CAPTURE(input);
  68. REQUIRE(deserializeJson(doc, input) ==
  69. DeserializationError::IncompleteInput);
  70. }
  71. }
  72. TEST_CASE("Invalid JSON string") {
  73. const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
  74. "'\\u000G'", "'\\u000/'", "'\\x1234'"};
  75. const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
  76. JsonDocument doc;
  77. for (size_t i = 0; i < testCount; i++) {
  78. const char* input = testCases[i];
  79. CAPTURE(input);
  80. REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
  81. }
  82. }
  83. TEST_CASE("Allocation of the key fails") {
  84. TimebombAllocator timebombAllocator(0);
  85. SpyingAllocator spyingAllocator(&timebombAllocator);
  86. JsonDocument doc(&spyingAllocator);
  87. SECTION("Quoted string, first member") {
  88. REQUIRE(deserializeJson(doc, "{\"example\":1}") ==
  89. DeserializationError::NoMemory);
  90. REQUIRE(spyingAllocator.log() ==
  91. AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
  92. }
  93. SECTION("Quoted string, second member") {
  94. timebombAllocator.setCountdown(3);
  95. REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
  96. DeserializationError::NoMemory);
  97. REQUIRE(spyingAllocator.log() ==
  98. AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
  99. << AllocatorLog::Reallocate(sizeofString(31),
  100. sizeofString(5))
  101. << AllocatorLog::Allocate(sizeofPool())
  102. << AllocatorLog::AllocateFail(sizeofString(31)));
  103. }
  104. SECTION("Non-Quoted string, first member") {
  105. REQUIRE(deserializeJson(doc, "{example:1}") ==
  106. DeserializationError::NoMemory);
  107. REQUIRE(spyingAllocator.log() ==
  108. AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
  109. }
  110. SECTION("Non-Quoted string, second member") {
  111. timebombAllocator.setCountdown(3);
  112. REQUIRE(deserializeJson(doc, "{hello:1,world}") ==
  113. DeserializationError::NoMemory);
  114. REQUIRE(spyingAllocator.log() ==
  115. AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
  116. << AllocatorLog::Reallocate(sizeofString(31),
  117. sizeofString(5))
  118. << AllocatorLog::Allocate(sizeofPool())
  119. << AllocatorLog::AllocateFail(sizeofString(31)));
  120. }
  121. }
  122. TEST_CASE("String allocation fails") {
  123. SpyingAllocator spyingAllocator(FailingAllocator::instance());
  124. JsonDocument doc(&spyingAllocator);
  125. SECTION("Input is const char*") {
  126. REQUIRE(deserializeJson(doc, "\"hello\"") ==
  127. DeserializationError::NoMemory);
  128. REQUIRE(spyingAllocator.log() ==
  129. AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
  130. }
  131. }
  132. TEST_CASE("Deduplicate values") {
  133. SpyingAllocator allocator;
  134. JsonDocument doc(&allocator);
  135. deserializeJson(doc, "[\"example\",\"example\"]");
  136. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  137. REQUIRE(allocator.log() == AllocatorLog()
  138. // pool
  139. << AllocatorLog::Allocate(sizeofPool())
  140. // string builder
  141. << AllocatorLog::Allocate(sizeofString(31))
  142. // string "example"
  143. << AllocatorLog::Reallocate(sizeofString(31),
  144. sizeofString(7))
  145. // string builder
  146. << AllocatorLog::Allocate(sizeofString(31))
  147. << AllocatorLog::Deallocate(sizeofString(31)));
  148. }
  149. TEST_CASE("Deduplicate keys") {
  150. SpyingAllocator allocator;
  151. JsonDocument doc(&allocator);
  152. deserializeJson(doc, "[{\"example\":1},{\"example\":2}]");
  153. const char* key1 = doc[0].as<JsonObject>().begin()->key().c_str();
  154. const char* key2 = doc[1].as<JsonObject>().begin()->key().c_str();
  155. CHECK(key1 == key2);
  156. REQUIRE(allocator.log() == AllocatorLog()
  157. // pool
  158. << AllocatorLog::Allocate(sizeofPool())
  159. // string builder
  160. << AllocatorLog::Allocate(sizeofString(31))
  161. // string "example"
  162. << AllocatorLog::Reallocate(sizeofString(31),
  163. sizeofString(7))
  164. // string builder
  165. << AllocatorLog::Allocate(sizeofString(31))
  166. << AllocatorLog::Deallocate(sizeofString(31)));
  167. }