string.cpp 6.7 KB

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