string.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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(4096);
  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(200);
  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(4096);
  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(4096);
  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(1);
  85. SpyingAllocator spyingAllocator(&timebombAllocator);
  86. JsonDocument doc(1024, &spyingAllocator);
  87. SECTION("Quoted string, first member") {
  88. REQUIRE(deserializeJson(doc, "{\"example\":1}") ==
  89. DeserializationError::NoMemory);
  90. REQUIRE(spyingAllocator.log() ==
  91. AllocatorLog() << AllocatorLog::Allocate(1024)
  92. << AllocatorLog::AllocateFail(sizeofString(31)));
  93. }
  94. SECTION("Quoted string, second member") {
  95. timebombAllocator.setCountdown(2);
  96. REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
  97. DeserializationError::NoMemory);
  98. REQUIRE(spyingAllocator.log() ==
  99. AllocatorLog() << AllocatorLog::Allocate(1024)
  100. << AllocatorLog::Allocate(sizeofString(31))
  101. << AllocatorLog::Reallocate(sizeofString(31),
  102. sizeofString(5))
  103. << AllocatorLog::AllocateFail(sizeofString(31)));
  104. }
  105. SECTION("Non-Quoted string, first member") {
  106. REQUIRE(deserializeJson(doc, "{example:1}") ==
  107. DeserializationError::NoMemory);
  108. REQUIRE(spyingAllocator.log() ==
  109. AllocatorLog() << AllocatorLog::Allocate(1024)
  110. << AllocatorLog::AllocateFail(sizeofString(31)));
  111. }
  112. SECTION("Non-Quoted string, second member") {
  113. timebombAllocator.setCountdown(2);
  114. REQUIRE(deserializeJson(doc, "{hello:1,world}") ==
  115. DeserializationError::NoMemory);
  116. REQUIRE(spyingAllocator.log() ==
  117. AllocatorLog() << AllocatorLog::Allocate(1024)
  118. << AllocatorLog::Allocate(sizeofString(31))
  119. << AllocatorLog::Reallocate(sizeofString(31),
  120. sizeofString(5))
  121. << AllocatorLog::AllocateFail(sizeofString(31)));
  122. }
  123. }
  124. TEST_CASE("String allocation fails") {
  125. SpyingAllocator spyingAllocator(FailingAllocator::instance());
  126. JsonDocument doc(0, &spyingAllocator);
  127. SECTION("Input is const char*") {
  128. REQUIRE(deserializeJson(doc, "\"hello\"") ==
  129. DeserializationError::NoMemory);
  130. REQUIRE(spyingAllocator.log() ==
  131. AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
  132. }
  133. SECTION("Input is const char*") {
  134. char hello[] = "\"hello\"";
  135. REQUIRE(deserializeJson(doc, hello) == DeserializationError::Ok);
  136. REQUIRE(spyingAllocator.log() == AllocatorLog());
  137. }
  138. }
  139. TEST_CASE("Deduplicate values") {
  140. JsonDocument doc(1024);
  141. deserializeJson(doc, "[\"example\",\"example\"]");
  142. CHECK(doc.memoryUsage() == sizeofArray(2) + sizeofString(7));
  143. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  144. }
  145. TEST_CASE("Deduplicate keys") {
  146. JsonDocument doc(1024);
  147. deserializeJson(doc, "[{\"example\":1},{\"example\":2}]");
  148. CHECK(doc.memoryUsage() ==
  149. 2 * sizeofObject(1) + sizeofArray(2) + sizeofString(7));
  150. const char* key1 = doc[0].as<JsonObject>().begin()->key().c_str();
  151. const char* key2 = doc[1].as<JsonObject>().begin()->key().c_str();
  152. CHECK(key1 == key2);
  153. }