1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ (supporting code) 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 8c5f01b2fSopenharmony_ci 9c5f01b2fSopenharmony_ci#include "doctest_compatibility.h" 10c5f01b2fSopenharmony_ci 11c5f01b2fSopenharmony_ci// for some reason including this after the json header leads to linker errors with VS 2017... 12c5f01b2fSopenharmony_ci#include <locale> 13c5f01b2fSopenharmony_ci 14c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp> 15c5f01b2fSopenharmony_ciusing nlohmann::json; 16c5f01b2fSopenharmony_ci 17c5f01b2fSopenharmony_ci#include <fstream> 18c5f01b2fSopenharmony_ci#include <sstream> 19c5f01b2fSopenharmony_ci#include <iostream> 20c5f01b2fSopenharmony_ci#include <iomanip> 21c5f01b2fSopenharmony_ci#include "make_test_data_available.hpp" 22c5f01b2fSopenharmony_ci 23c5f01b2fSopenharmony_ci// this test suite uses static variables with non-trivial destructors 24c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING_PUSH 25c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors") 26c5f01b2fSopenharmony_ci 27c5f01b2fSopenharmony_cinamespace 28c5f01b2fSopenharmony_ci{ 29c5f01b2fSopenharmony_ciextern size_t calls; 30c5f01b2fSopenharmony_cisize_t calls = 0; 31c5f01b2fSopenharmony_ci 32c5f01b2fSopenharmony_civoid check_utf8dump(bool success_expected, int byte1, int byte2, int byte3, int byte4); 33c5f01b2fSopenharmony_ci 34c5f01b2fSopenharmony_civoid check_utf8dump(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1) 35c5f01b2fSopenharmony_ci{ 36c5f01b2fSopenharmony_ci static std::string json_string; 37c5f01b2fSopenharmony_ci json_string.clear(); 38c5f01b2fSopenharmony_ci 39c5f01b2fSopenharmony_ci CAPTURE(byte1) 40c5f01b2fSopenharmony_ci CAPTURE(byte2) 41c5f01b2fSopenharmony_ci CAPTURE(byte3) 42c5f01b2fSopenharmony_ci CAPTURE(byte4) 43c5f01b2fSopenharmony_ci 44c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte1)); 45c5f01b2fSopenharmony_ci 46c5f01b2fSopenharmony_ci if (byte2 != -1) 47c5f01b2fSopenharmony_ci { 48c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte2)); 49c5f01b2fSopenharmony_ci } 50c5f01b2fSopenharmony_ci 51c5f01b2fSopenharmony_ci if (byte3 != -1) 52c5f01b2fSopenharmony_ci { 53c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte3)); 54c5f01b2fSopenharmony_ci } 55c5f01b2fSopenharmony_ci 56c5f01b2fSopenharmony_ci if (byte4 != -1) 57c5f01b2fSopenharmony_ci { 58c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte4)); 59c5f01b2fSopenharmony_ci } 60c5f01b2fSopenharmony_ci 61c5f01b2fSopenharmony_ci CAPTURE(json_string) 62c5f01b2fSopenharmony_ci 63c5f01b2fSopenharmony_ci // store the string in a JSON value 64c5f01b2fSopenharmony_ci static json j; 65c5f01b2fSopenharmony_ci static json j2; 66c5f01b2fSopenharmony_ci j = json_string; 67c5f01b2fSopenharmony_ci j2 = "abc" + json_string + "xyz"; 68c5f01b2fSopenharmony_ci 69c5f01b2fSopenharmony_ci static std::string s_ignored; 70c5f01b2fSopenharmony_ci static std::string s_ignored2; 71c5f01b2fSopenharmony_ci static std::string s_ignored_ascii; 72c5f01b2fSopenharmony_ci static std::string s_ignored2_ascii; 73c5f01b2fSopenharmony_ci static std::string s_replaced; 74c5f01b2fSopenharmony_ci static std::string s_replaced2; 75c5f01b2fSopenharmony_ci static std::string s_replaced_ascii; 76c5f01b2fSopenharmony_ci static std::string s_replaced2_ascii; 77c5f01b2fSopenharmony_ci 78c5f01b2fSopenharmony_ci // dumping with ignore/replace must not throw in any case 79c5f01b2fSopenharmony_ci s_ignored = j.dump(-1, ' ', false, json::error_handler_t::ignore); 80c5f01b2fSopenharmony_ci s_ignored2 = j2.dump(-1, ' ', false, json::error_handler_t::ignore); 81c5f01b2fSopenharmony_ci s_ignored_ascii = j.dump(-1, ' ', true, json::error_handler_t::ignore); 82c5f01b2fSopenharmony_ci s_ignored2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::ignore); 83c5f01b2fSopenharmony_ci s_replaced = j.dump(-1, ' ', false, json::error_handler_t::replace); 84c5f01b2fSopenharmony_ci s_replaced2 = j2.dump(-1, ' ', false, json::error_handler_t::replace); 85c5f01b2fSopenharmony_ci s_replaced_ascii = j.dump(-1, ' ', true, json::error_handler_t::replace); 86c5f01b2fSopenharmony_ci s_replaced2_ascii = j2.dump(-1, ' ', true, json::error_handler_t::replace); 87c5f01b2fSopenharmony_ci 88c5f01b2fSopenharmony_ci if (success_expected) 89c5f01b2fSopenharmony_ci { 90c5f01b2fSopenharmony_ci static std::string s_strict; 91c5f01b2fSopenharmony_ci // strict mode must not throw if success is expected 92c5f01b2fSopenharmony_ci s_strict = j.dump(); 93c5f01b2fSopenharmony_ci // all dumps should agree on the string 94c5f01b2fSopenharmony_ci CHECK(s_strict == s_ignored); 95c5f01b2fSopenharmony_ci CHECK(s_strict == s_replaced); 96c5f01b2fSopenharmony_ci } 97c5f01b2fSopenharmony_ci else 98c5f01b2fSopenharmony_ci { 99c5f01b2fSopenharmony_ci // strict mode must throw if success is not expected 100c5f01b2fSopenharmony_ci CHECK_THROWS_AS(j.dump(), json::type_error&); 101c5f01b2fSopenharmony_ci // ignore and replace must create different dumps 102c5f01b2fSopenharmony_ci CHECK(s_ignored != s_replaced); 103c5f01b2fSopenharmony_ci 104c5f01b2fSopenharmony_ci // check that replace string contains a replacement character 105c5f01b2fSopenharmony_ci CHECK(s_replaced.find("\xEF\xBF\xBD") != std::string::npos); 106c5f01b2fSopenharmony_ci } 107c5f01b2fSopenharmony_ci 108c5f01b2fSopenharmony_ci // check that prefix and suffix are preserved 109c5f01b2fSopenharmony_ci CHECK(s_ignored2.substr(1, 3) == "abc"); 110c5f01b2fSopenharmony_ci CHECK(s_ignored2.substr(s_ignored2.size() - 4, 3) == "xyz"); 111c5f01b2fSopenharmony_ci CHECK(s_ignored2_ascii.substr(1, 3) == "abc"); 112c5f01b2fSopenharmony_ci CHECK(s_ignored2_ascii.substr(s_ignored2_ascii.size() - 4, 3) == "xyz"); 113c5f01b2fSopenharmony_ci CHECK(s_replaced2.substr(1, 3) == "abc"); 114c5f01b2fSopenharmony_ci CHECK(s_replaced2.substr(s_replaced2.size() - 4, 3) == "xyz"); 115c5f01b2fSopenharmony_ci CHECK(s_replaced2_ascii.substr(1, 3) == "abc"); 116c5f01b2fSopenharmony_ci CHECK(s_replaced2_ascii.substr(s_replaced2_ascii.size() - 4, 3) == "xyz"); 117c5f01b2fSopenharmony_ci} 118c5f01b2fSopenharmony_ci 119c5f01b2fSopenharmony_civoid check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4); 120c5f01b2fSopenharmony_ci 121c5f01b2fSopenharmony_ci// create and check a JSON string with up to four UTF-8 bytes 122c5f01b2fSopenharmony_civoid check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1) 123c5f01b2fSopenharmony_ci{ 124c5f01b2fSopenharmony_ci if (++calls % 100000 == 0) 125c5f01b2fSopenharmony_ci { 126c5f01b2fSopenharmony_ci std::cout << calls << " of 455355 UTF-8 strings checked" << std::endl; 127c5f01b2fSopenharmony_ci } 128c5f01b2fSopenharmony_ci 129c5f01b2fSopenharmony_ci static std::string json_string; 130c5f01b2fSopenharmony_ci json_string = "\""; 131c5f01b2fSopenharmony_ci 132c5f01b2fSopenharmony_ci CAPTURE(byte1) 133c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte1)); 134c5f01b2fSopenharmony_ci 135c5f01b2fSopenharmony_ci if (byte2 != -1) 136c5f01b2fSopenharmony_ci { 137c5f01b2fSopenharmony_ci CAPTURE(byte2) 138c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte2)); 139c5f01b2fSopenharmony_ci } 140c5f01b2fSopenharmony_ci 141c5f01b2fSopenharmony_ci if (byte3 != -1) 142c5f01b2fSopenharmony_ci { 143c5f01b2fSopenharmony_ci CAPTURE(byte3) 144c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte3)); 145c5f01b2fSopenharmony_ci } 146c5f01b2fSopenharmony_ci 147c5f01b2fSopenharmony_ci if (byte4 != -1) 148c5f01b2fSopenharmony_ci { 149c5f01b2fSopenharmony_ci CAPTURE(byte4) 150c5f01b2fSopenharmony_ci json_string += std::string(1, static_cast<char>(byte4)); 151c5f01b2fSopenharmony_ci } 152c5f01b2fSopenharmony_ci 153c5f01b2fSopenharmony_ci json_string += "\""; 154c5f01b2fSopenharmony_ci 155c5f01b2fSopenharmony_ci CAPTURE(json_string) 156c5f01b2fSopenharmony_ci 157c5f01b2fSopenharmony_ci json _; 158c5f01b2fSopenharmony_ci if (success_expected) 159c5f01b2fSopenharmony_ci { 160c5f01b2fSopenharmony_ci CHECK_NOTHROW(_ = json::parse(json_string)); 161c5f01b2fSopenharmony_ci } 162c5f01b2fSopenharmony_ci else 163c5f01b2fSopenharmony_ci { 164c5f01b2fSopenharmony_ci CHECK_THROWS_AS(_ = json::parse(json_string), json::parse_error&); 165c5f01b2fSopenharmony_ci } 166c5f01b2fSopenharmony_ci} 167c5f01b2fSopenharmony_ci} // namespace 168c5f01b2fSopenharmony_ci 169c5f01b2fSopenharmony_ciTEST_CASE("Unicode (2/5)" * doctest::skip()) 170c5f01b2fSopenharmony_ci{ 171c5f01b2fSopenharmony_ci SECTION("RFC 3629") 172c5f01b2fSopenharmony_ci { 173c5f01b2fSopenharmony_ci /* 174c5f01b2fSopenharmony_ci RFC 3629 describes in Sect. 4 the syntax of UTF-8 byte sequences as 175c5f01b2fSopenharmony_ci follows: 176c5f01b2fSopenharmony_ci 177c5f01b2fSopenharmony_ci A UTF-8 string is a sequence of octets representing a sequence of UCS 178c5f01b2fSopenharmony_ci characters. An octet sequence is valid UTF-8 only if it matches the 179c5f01b2fSopenharmony_ci following syntax, which is derived from the rules for encoding UTF-8 180c5f01b2fSopenharmony_ci and is expressed in the ABNF of [RFC2234]. 181c5f01b2fSopenharmony_ci 182c5f01b2fSopenharmony_ci UTF8-octets = *( UTF8-char ) 183c5f01b2fSopenharmony_ci UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4 184c5f01b2fSopenharmony_ci UTF8-1 = %x00-7F 185c5f01b2fSopenharmony_ci UTF8-2 = %xC2-DF UTF8-tail 186c5f01b2fSopenharmony_ci UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / 187c5f01b2fSopenharmony_ci %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) 188c5f01b2fSopenharmony_ci UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / 189c5f01b2fSopenharmony_ci %xF4 %x80-8F 2( UTF8-tail ) 190c5f01b2fSopenharmony_ci UTF8-tail = %x80-BF 191c5f01b2fSopenharmony_ci */ 192c5f01b2fSopenharmony_ci 193c5f01b2fSopenharmony_ci SECTION("ill-formed first byte") 194c5f01b2fSopenharmony_ci { 195c5f01b2fSopenharmony_ci for (int byte1 = 0x80; byte1 <= 0xC1; ++byte1) 196c5f01b2fSopenharmony_ci { 197c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 198c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 199c5f01b2fSopenharmony_ci } 200c5f01b2fSopenharmony_ci 201c5f01b2fSopenharmony_ci for (int byte1 = 0xF5; byte1 <= 0xFF; ++byte1) 202c5f01b2fSopenharmony_ci { 203c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 204c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 205c5f01b2fSopenharmony_ci } 206c5f01b2fSopenharmony_ci } 207c5f01b2fSopenharmony_ci 208c5f01b2fSopenharmony_ci SECTION("UTF8-1 (x00-x7F)") 209c5f01b2fSopenharmony_ci { 210c5f01b2fSopenharmony_ci SECTION("well-formed") 211c5f01b2fSopenharmony_ci { 212c5f01b2fSopenharmony_ci for (int byte1 = 0x00; byte1 <= 0x7F; ++byte1) 213c5f01b2fSopenharmony_ci { 214c5f01b2fSopenharmony_ci // unescaped control characters are parse errors in JSON 215c5f01b2fSopenharmony_ci if (0x00 <= byte1 && byte1 <= 0x1F) 216c5f01b2fSopenharmony_ci { 217c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 218c5f01b2fSopenharmony_ci continue; 219c5f01b2fSopenharmony_ci } 220c5f01b2fSopenharmony_ci 221c5f01b2fSopenharmony_ci // a single quote is a parse error in JSON 222c5f01b2fSopenharmony_ci if (byte1 == 0x22) 223c5f01b2fSopenharmony_ci { 224c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 225c5f01b2fSopenharmony_ci continue; 226c5f01b2fSopenharmony_ci } 227c5f01b2fSopenharmony_ci 228c5f01b2fSopenharmony_ci // a single backslash is a parse error in JSON 229c5f01b2fSopenharmony_ci if (byte1 == 0x5C) 230c5f01b2fSopenharmony_ci { 231c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 232c5f01b2fSopenharmony_ci continue; 233c5f01b2fSopenharmony_ci } 234c5f01b2fSopenharmony_ci 235c5f01b2fSopenharmony_ci // all other characters are OK 236c5f01b2fSopenharmony_ci check_utf8string(true, byte1); 237c5f01b2fSopenharmony_ci check_utf8dump(true, byte1); 238c5f01b2fSopenharmony_ci } 239c5f01b2fSopenharmony_ci } 240c5f01b2fSopenharmony_ci } 241c5f01b2fSopenharmony_ci 242c5f01b2fSopenharmony_ci SECTION("UTF8-2 (xC2-xDF UTF8-tail)") 243c5f01b2fSopenharmony_ci { 244c5f01b2fSopenharmony_ci SECTION("well-formed") 245c5f01b2fSopenharmony_ci { 246c5f01b2fSopenharmony_ci for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1) 247c5f01b2fSopenharmony_ci { 248c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 249c5f01b2fSopenharmony_ci { 250c5f01b2fSopenharmony_ci check_utf8string(true, byte1, byte2); 251c5f01b2fSopenharmony_ci check_utf8dump(true, byte1, byte2); 252c5f01b2fSopenharmony_ci } 253c5f01b2fSopenharmony_ci } 254c5f01b2fSopenharmony_ci } 255c5f01b2fSopenharmony_ci 256c5f01b2fSopenharmony_ci SECTION("ill-formed: missing second byte") 257c5f01b2fSopenharmony_ci { 258c5f01b2fSopenharmony_ci for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1) 259c5f01b2fSopenharmony_ci { 260c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 261c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 262c5f01b2fSopenharmony_ci } 263c5f01b2fSopenharmony_ci } 264c5f01b2fSopenharmony_ci 265c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong second byte") 266c5f01b2fSopenharmony_ci { 267c5f01b2fSopenharmony_ci for (int byte1 = 0xC2; byte1 <= 0xDF; ++byte1) 268c5f01b2fSopenharmony_ci { 269c5f01b2fSopenharmony_ci for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2) 270c5f01b2fSopenharmony_ci { 271c5f01b2fSopenharmony_ci // skip correct second byte 272c5f01b2fSopenharmony_ci if (0x80 <= byte2 && byte2 <= 0xBF) 273c5f01b2fSopenharmony_ci { 274c5f01b2fSopenharmony_ci continue; 275c5f01b2fSopenharmony_ci } 276c5f01b2fSopenharmony_ci 277c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2); 278c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2); 279c5f01b2fSopenharmony_ci } 280c5f01b2fSopenharmony_ci } 281c5f01b2fSopenharmony_ci } 282c5f01b2fSopenharmony_ci } 283c5f01b2fSopenharmony_ci 284c5f01b2fSopenharmony_ci SECTION("UTF8-3 (xE0 xA0-BF UTF8-tail)") 285c5f01b2fSopenharmony_ci { 286c5f01b2fSopenharmony_ci SECTION("well-formed") 287c5f01b2fSopenharmony_ci { 288c5f01b2fSopenharmony_ci for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1) 289c5f01b2fSopenharmony_ci { 290c5f01b2fSopenharmony_ci for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2) 291c5f01b2fSopenharmony_ci { 292c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 293c5f01b2fSopenharmony_ci { 294c5f01b2fSopenharmony_ci check_utf8string(true, byte1, byte2, byte3); 295c5f01b2fSopenharmony_ci check_utf8dump(true, byte1, byte2, byte3); 296c5f01b2fSopenharmony_ci } 297c5f01b2fSopenharmony_ci } 298c5f01b2fSopenharmony_ci } 299c5f01b2fSopenharmony_ci } 300c5f01b2fSopenharmony_ci 301c5f01b2fSopenharmony_ci SECTION("ill-formed: missing second byte") 302c5f01b2fSopenharmony_ci { 303c5f01b2fSopenharmony_ci for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1) 304c5f01b2fSopenharmony_ci { 305c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 306c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 307c5f01b2fSopenharmony_ci } 308c5f01b2fSopenharmony_ci } 309c5f01b2fSopenharmony_ci 310c5f01b2fSopenharmony_ci SECTION("ill-formed: missing third byte") 311c5f01b2fSopenharmony_ci { 312c5f01b2fSopenharmony_ci for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1) 313c5f01b2fSopenharmony_ci { 314c5f01b2fSopenharmony_ci for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2) 315c5f01b2fSopenharmony_ci { 316c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2); 317c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2); 318c5f01b2fSopenharmony_ci } 319c5f01b2fSopenharmony_ci } 320c5f01b2fSopenharmony_ci } 321c5f01b2fSopenharmony_ci 322c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong second byte") 323c5f01b2fSopenharmony_ci { 324c5f01b2fSopenharmony_ci for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1) 325c5f01b2fSopenharmony_ci { 326c5f01b2fSopenharmony_ci for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2) 327c5f01b2fSopenharmony_ci { 328c5f01b2fSopenharmony_ci // skip correct second byte 329c5f01b2fSopenharmony_ci if (0xA0 <= byte2 && byte2 <= 0xBF) 330c5f01b2fSopenharmony_ci { 331c5f01b2fSopenharmony_ci continue; 332c5f01b2fSopenharmony_ci } 333c5f01b2fSopenharmony_ci 334c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 335c5f01b2fSopenharmony_ci { 336c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 337c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 338c5f01b2fSopenharmony_ci } 339c5f01b2fSopenharmony_ci } 340c5f01b2fSopenharmony_ci } 341c5f01b2fSopenharmony_ci } 342c5f01b2fSopenharmony_ci 343c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong third byte") 344c5f01b2fSopenharmony_ci { 345c5f01b2fSopenharmony_ci for (int byte1 = 0xE0; byte1 <= 0xE0; ++byte1) 346c5f01b2fSopenharmony_ci { 347c5f01b2fSopenharmony_ci for (int byte2 = 0xA0; byte2 <= 0xBF; ++byte2) 348c5f01b2fSopenharmony_ci { 349c5f01b2fSopenharmony_ci for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3) 350c5f01b2fSopenharmony_ci { 351c5f01b2fSopenharmony_ci // skip correct third byte 352c5f01b2fSopenharmony_ci if (0x80 <= byte3 && byte3 <= 0xBF) 353c5f01b2fSopenharmony_ci { 354c5f01b2fSopenharmony_ci continue; 355c5f01b2fSopenharmony_ci } 356c5f01b2fSopenharmony_ci 357c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 358c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 359c5f01b2fSopenharmony_ci } 360c5f01b2fSopenharmony_ci } 361c5f01b2fSopenharmony_ci } 362c5f01b2fSopenharmony_ci } 363c5f01b2fSopenharmony_ci } 364c5f01b2fSopenharmony_ci 365c5f01b2fSopenharmony_ci SECTION("UTF8-3 (xE1-xEC UTF8-tail UTF8-tail)") 366c5f01b2fSopenharmony_ci { 367c5f01b2fSopenharmony_ci SECTION("well-formed") 368c5f01b2fSopenharmony_ci { 369c5f01b2fSopenharmony_ci for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1) 370c5f01b2fSopenharmony_ci { 371c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 372c5f01b2fSopenharmony_ci { 373c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 374c5f01b2fSopenharmony_ci { 375c5f01b2fSopenharmony_ci check_utf8string(true, byte1, byte2, byte3); 376c5f01b2fSopenharmony_ci check_utf8dump(true, byte1, byte2, byte3); 377c5f01b2fSopenharmony_ci } 378c5f01b2fSopenharmony_ci } 379c5f01b2fSopenharmony_ci } 380c5f01b2fSopenharmony_ci } 381c5f01b2fSopenharmony_ci 382c5f01b2fSopenharmony_ci SECTION("ill-formed: missing second byte") 383c5f01b2fSopenharmony_ci { 384c5f01b2fSopenharmony_ci for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1) 385c5f01b2fSopenharmony_ci { 386c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 387c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 388c5f01b2fSopenharmony_ci } 389c5f01b2fSopenharmony_ci } 390c5f01b2fSopenharmony_ci 391c5f01b2fSopenharmony_ci SECTION("ill-formed: missing third byte") 392c5f01b2fSopenharmony_ci { 393c5f01b2fSopenharmony_ci for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1) 394c5f01b2fSopenharmony_ci { 395c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 396c5f01b2fSopenharmony_ci { 397c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2); 398c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2); 399c5f01b2fSopenharmony_ci } 400c5f01b2fSopenharmony_ci } 401c5f01b2fSopenharmony_ci } 402c5f01b2fSopenharmony_ci 403c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong second byte") 404c5f01b2fSopenharmony_ci { 405c5f01b2fSopenharmony_ci for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1) 406c5f01b2fSopenharmony_ci { 407c5f01b2fSopenharmony_ci for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2) 408c5f01b2fSopenharmony_ci { 409c5f01b2fSopenharmony_ci // skip correct second byte 410c5f01b2fSopenharmony_ci if (0x80 <= byte2 && byte2 <= 0xBF) 411c5f01b2fSopenharmony_ci { 412c5f01b2fSopenharmony_ci continue; 413c5f01b2fSopenharmony_ci } 414c5f01b2fSopenharmony_ci 415c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 416c5f01b2fSopenharmony_ci { 417c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 418c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 419c5f01b2fSopenharmony_ci } 420c5f01b2fSopenharmony_ci } 421c5f01b2fSopenharmony_ci } 422c5f01b2fSopenharmony_ci } 423c5f01b2fSopenharmony_ci 424c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong third byte") 425c5f01b2fSopenharmony_ci { 426c5f01b2fSopenharmony_ci for (int byte1 = 0xE1; byte1 <= 0xEC; ++byte1) 427c5f01b2fSopenharmony_ci { 428c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 429c5f01b2fSopenharmony_ci { 430c5f01b2fSopenharmony_ci for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3) 431c5f01b2fSopenharmony_ci { 432c5f01b2fSopenharmony_ci // skip correct third byte 433c5f01b2fSopenharmony_ci if (0x80 <= byte3 && byte3 <= 0xBF) 434c5f01b2fSopenharmony_ci { 435c5f01b2fSopenharmony_ci continue; 436c5f01b2fSopenharmony_ci } 437c5f01b2fSopenharmony_ci 438c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 439c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 440c5f01b2fSopenharmony_ci } 441c5f01b2fSopenharmony_ci } 442c5f01b2fSopenharmony_ci } 443c5f01b2fSopenharmony_ci } 444c5f01b2fSopenharmony_ci } 445c5f01b2fSopenharmony_ci 446c5f01b2fSopenharmony_ci SECTION("UTF8-3 (xED x80-9F UTF8-tail)") 447c5f01b2fSopenharmony_ci { 448c5f01b2fSopenharmony_ci SECTION("well-formed") 449c5f01b2fSopenharmony_ci { 450c5f01b2fSopenharmony_ci for (int byte1 = 0xED; byte1 <= 0xED; ++byte1) 451c5f01b2fSopenharmony_ci { 452c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2) 453c5f01b2fSopenharmony_ci { 454c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 455c5f01b2fSopenharmony_ci { 456c5f01b2fSopenharmony_ci check_utf8string(true, byte1, byte2, byte3); 457c5f01b2fSopenharmony_ci check_utf8dump(true, byte1, byte2, byte3); 458c5f01b2fSopenharmony_ci } 459c5f01b2fSopenharmony_ci } 460c5f01b2fSopenharmony_ci } 461c5f01b2fSopenharmony_ci } 462c5f01b2fSopenharmony_ci 463c5f01b2fSopenharmony_ci SECTION("ill-formed: missing second byte") 464c5f01b2fSopenharmony_ci { 465c5f01b2fSopenharmony_ci for (int byte1 = 0xED; byte1 <= 0xED; ++byte1) 466c5f01b2fSopenharmony_ci { 467c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 468c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 469c5f01b2fSopenharmony_ci } 470c5f01b2fSopenharmony_ci } 471c5f01b2fSopenharmony_ci 472c5f01b2fSopenharmony_ci SECTION("ill-formed: missing third byte") 473c5f01b2fSopenharmony_ci { 474c5f01b2fSopenharmony_ci for (int byte1 = 0xED; byte1 <= 0xED; ++byte1) 475c5f01b2fSopenharmony_ci { 476c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2) 477c5f01b2fSopenharmony_ci { 478c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2); 479c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2); 480c5f01b2fSopenharmony_ci } 481c5f01b2fSopenharmony_ci } 482c5f01b2fSopenharmony_ci } 483c5f01b2fSopenharmony_ci 484c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong second byte") 485c5f01b2fSopenharmony_ci { 486c5f01b2fSopenharmony_ci for (int byte1 = 0xED; byte1 <= 0xED; ++byte1) 487c5f01b2fSopenharmony_ci { 488c5f01b2fSopenharmony_ci for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2) 489c5f01b2fSopenharmony_ci { 490c5f01b2fSopenharmony_ci // skip correct second byte 491c5f01b2fSopenharmony_ci if (0x80 <= byte2 && byte2 <= 0x9F) 492c5f01b2fSopenharmony_ci { 493c5f01b2fSopenharmony_ci continue; 494c5f01b2fSopenharmony_ci } 495c5f01b2fSopenharmony_ci 496c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 497c5f01b2fSopenharmony_ci { 498c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 499c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 500c5f01b2fSopenharmony_ci } 501c5f01b2fSopenharmony_ci } 502c5f01b2fSopenharmony_ci } 503c5f01b2fSopenharmony_ci } 504c5f01b2fSopenharmony_ci 505c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong third byte") 506c5f01b2fSopenharmony_ci { 507c5f01b2fSopenharmony_ci for (int byte1 = 0xED; byte1 <= 0xED; ++byte1) 508c5f01b2fSopenharmony_ci { 509c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0x9F; ++byte2) 510c5f01b2fSopenharmony_ci { 511c5f01b2fSopenharmony_ci for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3) 512c5f01b2fSopenharmony_ci { 513c5f01b2fSopenharmony_ci // skip correct third byte 514c5f01b2fSopenharmony_ci if (0x80 <= byte3 && byte3 <= 0xBF) 515c5f01b2fSopenharmony_ci { 516c5f01b2fSopenharmony_ci continue; 517c5f01b2fSopenharmony_ci } 518c5f01b2fSopenharmony_ci 519c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 520c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 521c5f01b2fSopenharmony_ci } 522c5f01b2fSopenharmony_ci } 523c5f01b2fSopenharmony_ci } 524c5f01b2fSopenharmony_ci } 525c5f01b2fSopenharmony_ci } 526c5f01b2fSopenharmony_ci 527c5f01b2fSopenharmony_ci SECTION("UTF8-3 (xEE-xEF UTF8-tail UTF8-tail)") 528c5f01b2fSopenharmony_ci { 529c5f01b2fSopenharmony_ci SECTION("well-formed") 530c5f01b2fSopenharmony_ci { 531c5f01b2fSopenharmony_ci for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1) 532c5f01b2fSopenharmony_ci { 533c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 534c5f01b2fSopenharmony_ci { 535c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 536c5f01b2fSopenharmony_ci { 537c5f01b2fSopenharmony_ci check_utf8string(true, byte1, byte2, byte3); 538c5f01b2fSopenharmony_ci check_utf8dump(true, byte1, byte2, byte3); 539c5f01b2fSopenharmony_ci } 540c5f01b2fSopenharmony_ci } 541c5f01b2fSopenharmony_ci } 542c5f01b2fSopenharmony_ci } 543c5f01b2fSopenharmony_ci 544c5f01b2fSopenharmony_ci SECTION("ill-formed: missing second byte") 545c5f01b2fSopenharmony_ci { 546c5f01b2fSopenharmony_ci for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1) 547c5f01b2fSopenharmony_ci { 548c5f01b2fSopenharmony_ci check_utf8string(false, byte1); 549c5f01b2fSopenharmony_ci check_utf8dump(false, byte1); 550c5f01b2fSopenharmony_ci } 551c5f01b2fSopenharmony_ci } 552c5f01b2fSopenharmony_ci 553c5f01b2fSopenharmony_ci SECTION("ill-formed: missing third byte") 554c5f01b2fSopenharmony_ci { 555c5f01b2fSopenharmony_ci for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1) 556c5f01b2fSopenharmony_ci { 557c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 558c5f01b2fSopenharmony_ci { 559c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2); 560c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2); 561c5f01b2fSopenharmony_ci } 562c5f01b2fSopenharmony_ci } 563c5f01b2fSopenharmony_ci } 564c5f01b2fSopenharmony_ci 565c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong second byte") 566c5f01b2fSopenharmony_ci { 567c5f01b2fSopenharmony_ci for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1) 568c5f01b2fSopenharmony_ci { 569c5f01b2fSopenharmony_ci for (int byte2 = 0x00; byte2 <= 0xFF; ++byte2) 570c5f01b2fSopenharmony_ci { 571c5f01b2fSopenharmony_ci // skip correct second byte 572c5f01b2fSopenharmony_ci if (0x80 <= byte2 && byte2 <= 0xBF) 573c5f01b2fSopenharmony_ci { 574c5f01b2fSopenharmony_ci continue; 575c5f01b2fSopenharmony_ci } 576c5f01b2fSopenharmony_ci 577c5f01b2fSopenharmony_ci for (int byte3 = 0x80; byte3 <= 0xBF; ++byte3) 578c5f01b2fSopenharmony_ci { 579c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 580c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 581c5f01b2fSopenharmony_ci } 582c5f01b2fSopenharmony_ci } 583c5f01b2fSopenharmony_ci } 584c5f01b2fSopenharmony_ci } 585c5f01b2fSopenharmony_ci 586c5f01b2fSopenharmony_ci SECTION("ill-formed: wrong third byte") 587c5f01b2fSopenharmony_ci { 588c5f01b2fSopenharmony_ci for (int byte1 = 0xEE; byte1 <= 0xEF; ++byte1) 589c5f01b2fSopenharmony_ci { 590c5f01b2fSopenharmony_ci for (int byte2 = 0x80; byte2 <= 0xBF; ++byte2) 591c5f01b2fSopenharmony_ci { 592c5f01b2fSopenharmony_ci for (int byte3 = 0x00; byte3 <= 0xFF; ++byte3) 593c5f01b2fSopenharmony_ci { 594c5f01b2fSopenharmony_ci // skip correct third byte 595c5f01b2fSopenharmony_ci if (0x80 <= byte3 && byte3 <= 0xBF) 596c5f01b2fSopenharmony_ci { 597c5f01b2fSopenharmony_ci continue; 598c5f01b2fSopenharmony_ci } 599c5f01b2fSopenharmony_ci 600c5f01b2fSopenharmony_ci check_utf8string(false, byte1, byte2, byte3); 601c5f01b2fSopenharmony_ci check_utf8dump(false, byte1, byte2, byte3); 602c5f01b2fSopenharmony_ci } 603c5f01b2fSopenharmony_ci } 604c5f01b2fSopenharmony_ci } 605c5f01b2fSopenharmony_ci } 606c5f01b2fSopenharmony_ci } 607c5f01b2fSopenharmony_ci } 608c5f01b2fSopenharmony_ci} 609c5f01b2fSopenharmony_ci 610c5f01b2fSopenharmony_ciDOCTEST_CLANG_SUPPRESS_WARNING_POP 611