string.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. using ArduinoJson::detail::sizeofArray;
  8. using ArduinoJson::detail::sizeofObject;
  9. using ArduinoJson::detail::sizeofString;
  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(4096);
  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(200);
  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(4096);
  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("Invalid JSON string") {
  72. const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
  73. "'\\u000G'", "'\\u000/'", "'\\x1234'"};
  74. const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
  75. JsonDocument doc(4096);
  76. for (size_t i = 0; i < testCount; i++) {
  77. const char* input = testCases[i];
  78. CAPTURE(input);
  79. REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
  80. }
  81. }
  82. TEST_CASE("Not enough room to save the key") {
  83. JsonDocument doc(sizeofObject(1) + sizeofString(7));
  84. SECTION("Quoted string") {
  85. REQUIRE(deserializeJson(doc, "{\"example\":1}") ==
  86. DeserializationError::Ok);
  87. REQUIRE(deserializeJson(doc, "{\"accuracy\":1}") ==
  88. DeserializationError::NoMemory);
  89. REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
  90. DeserializationError::NoMemory); // fails in the second string
  91. }
  92. SECTION("Non-quoted string") {
  93. REQUIRE(deserializeJson(doc, "{example:1}") == DeserializationError::Ok);
  94. REQUIRE(deserializeJson(doc, "{accuracy:1}") ==
  95. DeserializationError::NoMemory);
  96. REQUIRE(deserializeJson(doc, "{hello:1,world}") ==
  97. DeserializationError::NoMemory); // fails in the second string
  98. }
  99. }
  100. TEST_CASE("Empty memory pool") {
  101. // NOLINTNEXTLINE(clang-analyzer-optin.portability.UnixAPI)
  102. JsonDocument doc(0);
  103. SECTION("Input is const char*") {
  104. REQUIRE(deserializeJson(doc, "\"hello\"") ==
  105. DeserializationError::NoMemory);
  106. REQUIRE(deserializeJson(doc, "\"\"") == DeserializationError::NoMemory);
  107. }
  108. SECTION("Input is const char*") {
  109. char hello[] = "\"hello\"";
  110. REQUIRE(deserializeJson(doc, hello) == DeserializationError::Ok);
  111. char empty[] = "\"hello\"";
  112. REQUIRE(deserializeJson(doc, empty) == DeserializationError::Ok);
  113. }
  114. }
  115. TEST_CASE("Deduplicate values") {
  116. JsonDocument doc(1024);
  117. deserializeJson(doc, "[\"example\",\"example\"]");
  118. CHECK(doc.memoryUsage() == sizeofArray(2) + sizeofString(7));
  119. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  120. }
  121. TEST_CASE("Deduplicate keys") {
  122. JsonDocument doc(1024);
  123. deserializeJson(doc, "[{\"example\":1},{\"example\":2}]");
  124. CHECK(doc.memoryUsage() ==
  125. 2 * sizeofObject(1) + sizeofArray(2) + sizeofString(7));
  126. const char* key1 = doc[0].as<JsonObject>().begin()->key().c_str();
  127. const char* key2 = doc[1].as<JsonObject>().begin()->key().c_str();
  128. CHECK(key1 == key2);
  129. }